📄 codestream.cpp
字号:
kd_code_alloc *new_alloc = new kd_code_alloc; new_alloc->next = alloc; alloc = new_alloc; int n; for (n=0; n < (KD_CODE_ALLOC_NUM-1); n++) alloc->bufs[n].next = &(alloc->bufs[n+1]); alloc->bufs[n].next = free; free = &(alloc->bufs[0]); total_buffers += KD_CODE_ALLOC_NUM; } kd_code_buffer *result = free; free = result->next; result->next = NULL; num_allocated_buffers++; if (num_allocated_buffers > peak_allocated_buffers) peak_allocated_buffers++; return result;}/*****************************************************************************//* kd_buf_server::release *//*****************************************************************************/void kd_buf_server::release(kd_code_buffer *buf){ assert(num_allocated_buffers > 0); buf->next = free; free = buf; num_allocated_buffers--;}/* ========================================================================= *//* kd_packet_sequencer *//* ========================================================================= *//*****************************************************************************//* kd_packet_sequencer::kd_packet_sequencer *//*****************************************************************************/kd_packet_sequencer::kd_packet_sequencer(kd_tile *tile){ int c, r; kd_tile_comp *tc; kd_resolution *res; assert(tile->initialized); this->tile = tile; max_dwt_levels = 0; common_grids = true; for (c=0; c < tile->num_components; c++) { tc = tile->comps + c; if (tc->dwt_levels > max_dwt_levels) max_dwt_levels = tc->dwt_levels; if (!(is_power_2(tc->sub_sampling.x) && is_power_2(tc->sub_sampling.y))) common_grids = false; for (r=0; r <= tc->dwt_levels; r++) { int inc; res = tc->resolutions + r; inc = res->precinct_partition.size.x; inc <<= (tc->dwt_levels-r); inc *= tc->sub_sampling.x; if ((r == 0) || (inc < tc->grid_inc.x)) tc->grid_inc.x = inc; inc = res->precinct_partition.size.y; inc <<= (tc->dwt_levels-r); inc *= tc->sub_sampling.y; if ((r == 0) || (inc < tc->grid_inc.y)) tc->grid_inc.y = inc; } tc->grid_min = tile->dims.pos - tile->coding_origin; tc->grid_min.x = tc->grid_inc.x * floor_ratio(tc->grid_min.x,tc->grid_inc.x); tc->grid_min.y = tc->grid_inc.y * floor_ratio(tc->grid_min.y,tc->grid_inc.y); tc->grid_min += tile->coding_origin; } grid_lim = tile->dims.pos + tile->dims.size; poc = NULL; next_poc_record = 0; next_progression();}/*****************************************************************************//* kd_packet_sequencer::save_state *//*****************************************************************************/void kd_packet_sequencer::save_state(){ for (int c=0; c < tile->num_components; c++) { kd_tile_comp *tc = tile->comps + c; for (int r=0; r <= tc->dwt_levels; r++) { kd_resolution *res = tc->resolutions + r; int num_precincts = res->precinct_indices.area(); for (int n=0; n < num_precincts; n++) { kd_precinct *precinct = res->precinct_refs[n]; if ((precinct != NULL) && (precinct != KD_EXPIRED_PRECINCT)) precinct->saved_next_layer_idx = precinct->next_layer_idx; } } } tile->saved_num_transferred_packets = tile->num_transferred_packets; saved_poc = poc;}/*****************************************************************************//* kd_packet_sequencer::restore_state *//*****************************************************************************/void kd_packet_sequencer::restore_state(){ for (int c=0; c < tile->num_components; c++) { kd_tile_comp *tc = tile->comps + c; for (int r=0; r <= tc->dwt_levels; r++) { kd_resolution *res = tc->resolutions + r; int num_precincts = res->precinct_indices.area(); for (int n=0; n < num_precincts; n++) { kd_precinct *precinct = res->precinct_refs[n]; if ((precinct != NULL) && (precinct != KD_EXPIRED_PRECINCT)) precinct->next_layer_idx = precinct->saved_next_layer_idx; } } } tile->num_transferred_packets = tile->saved_num_transferred_packets; poc = saved_poc; next_poc_record = 0; next_progression();}/*****************************************************************************//* kd_packet_sequencer::next_progression *//*****************************************************************************/bool kd_packet_sequencer::next_progression(){ if (poc == NULL) // Must be initial call. { poc = tile->codestream->siz->access_cluster(POC_params); assert(poc != NULL); poc = poc->access_relation(tile->tnum,-1); assert(poc != NULL); if (!poc->get(Porder,0,0,res_min)) poc = NULL; } if (poc == NULL) { // Get information from COD marker. kdu_params *cod = tile->codestream->siz->access_cluster(COD_params); cod = cod->access_relation(tile->tnum,-1); if (!cod->get(Corder,0,0,order)) assert(0); comp_min = res_min = 0; layer_lim = tile->num_layers; comp_lim = tile->num_components; res_lim = max_dwt_levels+1; } else { // Get information from POC marker. if (!poc->get(Porder,next_poc_record,0,res_min)) { // Need to access a new POC instance. int inst_idx = poc->get_instance(); inst_idx++; kdu_params *tmp_poc = poc->access_relation(tile->tnum,-1,inst_idx); if ((tmp_poc == NULL) || !tmp_poc->get(Porder,0,0,res_min)) { if (tile->codestream->in == NULL) { kdu_error e; e << "Supplied progression order attributes " "for tile " << tile->tnum << " are insuffient to cover " "all packets for the tile!"; } return false; } if (inst_idx >= tile->next_tpart) return false; // Need to generate a new tile-part first. poc = tmp_poc; next_poc_record = 0; } poc->get(Porder,next_poc_record,1,comp_min); poc->get(Porder,next_poc_record,2,layer_lim); poc->get(Porder,next_poc_record,3,res_lim); poc->get(Porder,next_poc_record,4,comp_lim); poc->get(Porder,next_poc_record,5,order); next_poc_record++; } if (layer_lim > tile->num_layers) layer_lim = tile->num_layers; if (comp_lim > tile->num_components) comp_lim = tile->num_components; if (res_lim > max_dwt_levels) res_lim = max_dwt_levels+1; layer_idx=0; comp_idx = comp_min; res_idx = res_min; pos.x=pos.y=0; bool spatial = false; if ((order == Corder_PCRL) || (order == Corder_RPCL)) { spatial = true; if (!common_grids) { kdu_error e; e << "Attempting to use a spatially progressive " "packet sequence where position order dominates component order. " "This is illegal when the component sub-sampling factors are not " "exact powers of 2!"; } for (int c=0; c < tile->num_components; c++) { kd_tile_comp *tc = tile->comps + c; if ((c == 0) || (tc->grid_inc.x < grid_inc.x)) { grid_inc.x = tc->grid_inc.x; grid_min.x = tc->grid_min.x; } if ((c == 0) || (tc->grid_inc.y < grid_inc.y)) { grid_inc.y = tc->grid_inc.y; grid_min.y = tc->grid_min.y; } } grid_loc = grid_min; } else if ((order == Corder_CPRL) && (comp_idx < comp_lim)) { spatial = true; grid_min = tile->comps[comp_idx].grid_min; grid_inc = tile->comps[comp_idx].grid_inc; grid_loc = grid_min; } if (spatial) { // Need to reset the precinct position indices in each resolution. for (int c=0; c < tile->num_components; c++) { kd_tile_comp *tc = tile->comps + c; for (int r=0; r <= tc->dwt_levels; r++) { kd_resolution *res = tc->resolutions + r; res->current_sequencer_pos.x = res->current_sequencer_pos.y = 0; } } } return true;}/*****************************************************************************//* kd_packet_sequencer::next_in_sequence *//*****************************************************************************/kd_precinct * kd_packet_sequencer::next_in_sequence(){ kd_precinct *result = NULL; if (tile->num_transferred_packets == tile->total_packets) return NULL; do { if (order == Corder_LRCP) result = next_in_lrcp(); else if (order == Corder_RLCP) result = next_in_rlcp(); else if (order == Corder_RPCL) result = next_in_rpcl(); else if (order == Corder_PCRL) result = next_in_pcrl(); else if (order == Corder_CPRL) result = next_in_cprl(); else assert(0); } while ((result == NULL) && next_progression()); return result;}/*****************************************************************************//* kd_packet_sequencer::next_in_lrcp *//*****************************************************************************/kd_precinct * kd_packet_sequencer::next_in_lrcp(){ for (; layer_idx < layer_lim; layer_idx++, res_idx=res_min) for (; res_idx < res_lim; res_idx++, comp_idx=comp_min) for (; comp_idx < comp_lim; comp_idx++, pos.y=0) { kd_tile_comp *tc = tile->comps + comp_idx; if (res_idx > tc->dwt_levels) continue; // Advance to next component. kd_resolution *res = tc->resolutions + res_idx; for (; pos.y < res->precinct_indices.size.y; pos.y++, pos.x=0) for (; pos.x < res->precinct_indices.size.x; pos.x++) { kd_precinct **refs = res->precinct_refs + pos.x + pos.y*res->precinct_indices.size.x; if (*refs == NULL) new kd_precinct(res,pos); if (*refs == KD_EXPIRED_PRECINCT) continue; // All layers already sequenced. assert((*refs)->next_layer_idx >= layer_idx); if ((*refs)->next_layer_idx == layer_idx) return *refs; } } return NULL;}/*****************************************************************************//* kd_packet_sequencer::next_in_rlcp *//*****************************************************************************/kd_precinct * kd_packet_sequencer::next_in_rlcp(){ for (; res_idx < res_lim; res_idx++, layer_idx=0) for (; layer_idx < layer_lim; layer_idx++, comp_idx=comp_min) for (; comp_idx < comp_lim; comp_idx++, pos.y=0) { kd_tile_comp *tc = tile->comps + comp_idx; if (res_idx > tc->dwt_levels) continue; // Advance to next component. kd_resolution *res = tc->resolutions + res_idx; for (; pos.y < res->precinct_indices.size.y; pos.y++, pos.x=0) for (; pos.x < res->precinct_indices.size.x; pos.x++) { kd_precinct **refs = res->precinct_refs + pos.x + pos.y*res->precinct_indices.size.x; if (*refs == NULL) new kd_precinct(res,pos); if (*refs == KD_EXPIRED_PRECINCT) continue; // All layers already sequenced. assert((*refs)->next_layer_idx >= layer_idx); if ((*refs)->next_layer_idx == layer_idx) return *refs; } } return NULL;}/*****************************************************************************//* kd_packet_sequencer::next_in_rpcl *//*****************************************************************************/kd_precinct * kd_packet_sequencer::next_in_rpcl(){ if (layer_lim <= 0) return NULL; for (; res_idx < res_lim; res_idx++, grid_loc.y=grid_min.y) for (; grid_loc.y < grid_lim.y; grid_loc.y += grid_inc.y, grid_loc.x=grid_min.x) for (; grid_loc.x < grid_lim.x; grid_loc.x += grid_inc.x, comp_idx=comp_min) for (; comp_idx < comp_lim; comp_idx++) { kd_tile_comp *tc = tile->comps + comp_idx; if (res_idx > tc->dwt_levels) continue; // Advance to next component.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -