📄 compressed.cpp
字号:
if (state->roi_weight < 0.0F) return false; energy_weight = state->roi_weight * state->roi_weight; return true;}/*****************************************************************************//* kdu_subband::get_dims *//*****************************************************************************/void kdu_subband::get_dims(kdu_dims &result) /* This is the only place where we need to be particularly careful about mapping apparent dimensions through geometric transformations. The reason is that high-pass subband coordinates are notionally based on an origin +1/2 a subband sample spacing beyond the origin of the real coordinate system. To flip these subbands, it is not sufficient to negate the coordinates of each constituent sample; we must also subtract 1. */{ kdu_coords band_idx = state->band_idx; result = state->region; state->codestream->to_apparent(result); if (state->codestream->transpose) band_idx.transpose(); if (state->codestream->hflip && band_idx.x) result.pos.x--; if (state->codestream->vflip && band_idx.y) result.pos.y--;}/*****************************************************************************//* kdu_subband::get_valid_blocks *//*****************************************************************************/void kdu_subband::get_valid_blocks(kdu_dims &indices){ indices = state->region_indices; state->codestream->to_apparent(indices);}/*****************************************************************************//* kdu_subband::get_block_size *//*****************************************************************************/void kdu_subband::get_block_size(kdu_coords &nominal_size, kdu_coords &first_size){ kdu_dims indices; kdu_coords first_idx; kdu_dims first_dims; nominal_size = state->block_partition.size; get_valid_blocks(indices); first_idx = indices.pos; state->codestream->from_apparent(first_idx); first_dims = state->block_partition; first_dims.pos.x += first_idx.x*first_dims.size.x; first_dims.pos.y += first_idx.y*first_dims.size.y; first_dims &= state->region; assert((!first_dims) || (first_dims.area() > 0)); first_size = first_dims.size; if (state->codestream->transpose) { nominal_size.transpose(); first_size.transpose(); }}/*****************************************************************************//* kdu_subband::open_block *//*****************************************************************************/kdu_block * kdu_subband::open_block(kdu_coords block_idx, int *return_tpart){ state->codestream->from_apparent(block_idx); block_idx -= state->region_indices.pos; assert((block_idx.x >= 0) && (block_idx.y >= 0) && (block_idx.x < state->region_indices.size.x) && (block_idx.y < state->region_indices.size.y)); block_idx += state->region_indices.pos; // Back to absolute indices. // First find the precinct to which this block belongs and the block index // within that precinct. kdu_coords precinct_idx = block_idx; precinct_idx.x >>= state->log2_blocks_per_precinct.x; precinct_idx.y >>= state->log2_blocks_per_precinct.y; // Create the precinct if necessary. kd_resolution *res = state->resolution; precinct_idx -= res->precinct_indices.pos; assert((precinct_idx.x >= 0) && (precinct_idx.y >= 0) && (precinct_idx.x < res->precinct_indices.size.x) && (precinct_idx.y < res->precinct_indices.size.y)); int precinct_num = precinct_idx.x + precinct_idx.y*res->precinct_indices.size.x; kd_precinct *precinct = res->precinct_refs[precinct_num]; assert(precinct != KD_EXPIRED_PRECINCT); if (precinct == NULL) { precinct = new kd_precinct(res,precinct_idx); assert(precinct == res->precinct_refs[precinct_num]); } // Load the precinct if necessary. kd_codestream *codestream = res->codestream; kd_tile *tile = res->tile_comp->tile; if (codestream->in != NULL) { while ((!tile->exhausted) && (precinct->next_layer_idx < precinct->num_layers)) { if ((tile != codestream->active_tile) && !tile->read_tile_part_header()) { assert(!tile->closed); // Otherwise, we could delete ourself. tile->finished_reading(); break; // Can't read any more information for this tile. } kd_precinct *seq = tile->sequencer->next_in_sequence(); if ((seq == NULL) || !seq->read_packet()) tile->read_tile_part_header(); } } // Initialize the block structure. kdu_dims band_dims = state->block_partition; band_dims.pos.x += block_idx.x*band_dims.size.x; band_dims.pos.y += block_idx.y*band_dims.size.y; band_dims &= state->dims; assert(band_dims.area() > 0); kd_precinct_band *pband = precinct->bands + state->which_band; block_idx -= pband->block_indices.pos; assert((block_idx.x >= 0) && (block_idx.y >= 0) && (block_idx.x < pband->block_indices.size.x) && (block_idx.y < pband->block_indices.size.y)); kdu_block *result = codestream->shared_block; codestream->shared_block = NULL; assert(result != NULL); result->precinct = precinct; result->which_block = block_idx.x + block_idx.y*pband->block_indices.size.x; kd_block *block = pband->blocks + result->which_block; // Set up the common fields (common to input and output codestream objects). result->size = band_dims.size; result->region = band_dims & state->region; result->region.pos -= band_dims.pos; result->modes = state->resolution->tile_comp->modes; result->orientation = state->which_band; result->K_max_prime = state->K_max_prime; // Retrieve compressed data, if necessary. if (codestream->in != NULL) block->retrieve_data(result,tile->num_apparent_layers); else if (!block->empty()) { kdu_error e; e << "Attempting to open the same code-block more than " "once for writing!"; } if (return_tpart != NULL) *return_tpart = precinct->resolution->tile_comp->tile->next_tpart-1; return result;}/*****************************************************************************//* kdu_subband::close_block *//*****************************************************************************/void kdu_subband::close_block(kdu_block *result){ kd_precinct *precinct = result->precinct; assert(precinct != NULL); assert(state->codestream->shared_block == NULL); state->codestream->shared_block = result; result->precinct = NULL; kd_precinct_band *pband = precinct->bands + state->which_band; kd_block *block = pband->blocks + result->which_block; assert(precinct->num_outstanding_blocks > 0); if (state->codestream->in != NULL) { // Release the block storage. if (!state->codestream->persistent) { block->cleanup(pband); precinct->num_outstanding_blocks--; if (precinct->num_outstanding_blocks == 0) delete precinct; } return; } // If we get here, we have an output block. bool trim_storage = false; if (state->codestream->stats != NULL) trim_storage = state->codestream->stats->update(result); assert(block->empty()); block->store_data(result,state->codestream->buf_server); precinct->num_outstanding_blocks--; if (trim_storage) state->codestream->trim_compressed_data();}/*****************************************************************************//* kdu_subband::get_conservative_slope_threshold *//*****************************************************************************/kdu_uint16 kdu_subband::get_conservative_slope_threshold(){ kd_codestream *codestream = state->codestream; kdu_uint16 result = 1; if (codestream->stats != NULL) result = codestream->stats->get_conservative_slope_threshold(); if (codestream->min_slope_threshold > result) result = codestream->min_slope_threshold; return result;}/* ========================================================================= *//* kd_precinct *//* ========================================================================= *//*****************************************************************************//* kd_precinct::kd_precinct *//*****************************************************************************/kd_precinct::kd_precinct(kd_resolution *resolution, kdu_coords pos_idx){ kd_tile_comp *comp = resolution->tile_comp; kd_tile *tile = comp->tile; kdu_dims dims, region; resolution->codestream->var_structure_new(sizeof(*this)); this->resolution = resolution; this->pos_idx = pos_idx; num_layers = tile->num_layers; next_layer_idx = 0; corrupted = false; assert((pos_idx.x < resolution->precinct_indices.size.x) && (pos_idx.y < resolution->precinct_indices.size.y)); int p = pos_idx.x + resolution->precinct_indices.size.x*pos_idx.y; resolution->precinct_refs[p] = this; pos_idx += resolution->precinct_indices.pos; dims = resolution->precinct_partition; dims.pos.x += pos_idx.x*dims.size.x; dims.pos.y += pos_idx.y*dims.size.y; dims &= resolution->dims; region = dims & resolution->region; bool discard = false; bool persistent = resolution->codestream->persistent; if ((!persistent) && ((!region) || (resolution->res_level > comp->apparent_dwt_levels) || (comp->cnum < tile->first_apparent_component) || (comp->cnum >= (tile->first_apparent_component+tile->num_apparent_components)))) { assert((dims.size.x>0) && (dims.size.y>0)); discard = true; // Mark all code-blocks in precinct for discarding. } // Initialize the precinct-bands. num_outstanding_blocks = 0; total_block_nodes = 0; int num_block_nodes; for (int b=resolution->min_band; b <= resolution->max_band; b++) { kd_precinct_band *pb = bands+b; kd_subband *subband = resolution->bands+b; pb->subband = subband; kdu_dims pband_dims = (b==LL_BAND)?dims:get_band_dims(dims,subband->band_idx); pb->block_indices = get_partition_indices(subband->block_partition,pband_dims); num_outstanding_blocks += pb->block_indices.area(); pb->blocks = kd_block::build_tree(pb->block_indices.size, &num_block_nodes); total_block_nodes += num_block_nodes; /* Finally, scan through the leaf nodes of the `blocks' array setting up the `modes' field and setting `num_passes' to indicate whether or not each block's contents can be discarded. */ // Get location and size of first code-block in the partition which // intersects with current precinct-band. kdu_dims block_dims = subband->block_partition; block_dims.pos.x += block_dims.size.x * pb->block_indices.pos.x; block_dims.pos.y += block_dims.size.y * pb->block_indices.pos.y; kdu_coords min = block_dims.pos; // So we can keep coming back here. kd_block *block = pb->blocks; int x, y; for (y=0, block_dims.pos.y=min.y; y < pb->block_indices.size.y; y++, block_dims.pos.y += block_dims.size.y) for (x=0, block_dims.pos.x=min.x; x < pb->block_indices.size.x; x++, block_dims.pos.x += block_dims.size.x, block++) { block->set_modes(resolution->tile_comp->modes); if ((!persistent) && (discard || !(block_dims & subband->region))) block->set_discard(); } } resolution->codestream->var_structure_new(sizeof(kd_block)*total_block_nodes); packet_bytes = NULL; // Create this array if and when we need it.}/*****************************************************************************//* kd_precinct::~kd_precinct *//*****************************************************************************/kd_precinct::~kd_precinct(){ resolution->codestream->var_structure_delete(sizeof(*this)); for (int b=resolution->min_band; b <= resolution->max_band; b++) { kd_precinct_band *pb = bands+b; if (pb->blocks != NULL) { int num_blocks = pb->block_indices.area(); for (int n=0; n < num_blocks; n++) pb->blocks[n].cl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -