📄 compressed.cpp
字号:
tc->resolutions = new kd_resolution[tc->dwt_levels+1]; codestream->var_structure_new(sizeof(kd_resolution)*(tc->dwt_levels+1)); kdu_dims res_dims = tc->dims; for (r=tc->dwt_levels; r >= 0; r--) { kd_resolution *res = tc->resolutions + r; res->codestream = codestream; res->tile_comp = tc; res->res_level = r; res->dwt_level = tc->dwt_levels - ((r==0)?0:(r-1)); res->propagate_roi = (res->dwt_level <= roi_levels); res->dims = res->region = res_dims; // Set up precincts. res->precinct_partition.pos = coding_origin; if (!use_precincts) { res->precinct_partition.size.x = 1<<15; res->precinct_partition.size.y = 1<<15; } else if (!(coc->get(Cprecincts,tc->dwt_levels-r,0, res->precinct_partition.size.y) && coc->get(Cprecincts,tc->dwt_levels-r,1, res->precinct_partition.size.x))) assert(0); check_coding_partition(res->precinct_partition); res->precinct_indices = get_partition_indices(res->precinct_partition,res_dims); int num_precincts = res->precinct_indices.area(); res->precinct_refs = new kd_precinct *[num_precincts]; codestream->var_structure_new(sizeof(kd_precinct *)*num_precincts); for (int n=0; n < num_precincts; n++) res->precinct_refs[n] = NULL; this->total_precincts += num_precincts; // Get energy weighting parameters. float level_weight; if (!coc->get(Clev_weights,tc->dwt_levels-r,0,level_weight)) level_weight = 1.0; double G_lo = kernels.get_energy_gain(KDU_SYNTHESIS_LOW,res->dwt_level); double G_hi = kernels.get_energy_gain(KDU_SYNTHESIS_HIGH,res->dwt_level); // Now build the subband structure. if (r==0) { res->min_band = res->max_band = LL_BAND; } else { res->min_band = 1; res->max_band = 3; } int b; kd_subband *band; res->bands = new kd_subband[res->max_band+1]; codestream->var_structure_new(sizeof(kd_subband)*(res->max_band+1)); for (b=res->min_band; b <= res->max_band; b++) { band = res->bands + b; band->codestream = codestream; band->resolution = res; band->which_band = b; band->band_idx.y = ((b==LH_BAND)||(b==HH_BAND))?1:0; band->band_idx.x = ((b==HL_BAND)||(b==HH_BAND))?1:0; if (r > 0) band->dims = band->region = get_band_dims(res_dims,band->band_idx); else band->dims = band->region = res_dims; // Determine quantization-related parameters for the subband. int max_band_idx = 3*tc->dwt_levels; int abs_band_idx = 3*(tc->dwt_levels-res->dwt_level) + b; assert((abs_band_idx >= 0) && (abs_band_idx <= max_band_idx)); if (tc->reversible) { if (!qcc->get(Qabs_ranges,abs_band_idx,0,band->epsilon)) assert(0); band->delta = 1.0F / ((float)(1<<codestream->precision[c])); } else { float delta; if (derived_quant) delta = base_delta * (float) (1<<(tc->dwt_levels-res->dwt_level)); else if (!qcc->get(Qabs_steps,abs_band_idx,0,delta)) assert(0); assert(delta > 0.0F); band->delta = delta; for (band->epsilon=0; delta < 1.0F; delta*=2.0F) band->epsilon++; assert(delta < 2.0F); } if (!qcc->get(Qguard,0,0,band->K_max)) assert(0); if (!rgc->get(Rweight,0,0,band->roi_weight)) band->roi_weight = -1.0F; // Indicates no ROI weights. band->K_max += band->epsilon - 1; if (!rgc->get(Rshift,0,0,band->K_max_prime)) band->K_max_prime = 0; band->K_max_prime += band->K_max; if (!coc->get(Cband_weights,max_band_idx-abs_band_idx,0, band->W_b)) band->W_b = 1.0F; band->W_b *= level_weight; if (b == LL_BAND) band->W_b = 1.0F; // Don't tamper with DC band. band->G_b = (float) (((band->band_idx.x)?G_hi:G_lo)*((band->band_idx.y)?G_hi:G_lo)); if (use_ycc) { // Need to include colour transform synthesis gains. if (tc->reversible) { if (c == 0) band->G_b *=(float)( 1.0*1.0 + 1.0*1.0 + 1.0*1.0); else if ((c == 1) || (c == 2)) band->G_b *=(float)(0.75*0.75 + 0.25*0.25 + 0.25*0.25); } else { double alpha_R=0.299, alpha_G=0.587, alpha_B=0.114; if (c == 0) band->G_b *= (float)( 1.0*1.0 + 1.0*1.0 + 1.0*1.0); else if (c == 1) { double f1 = 2.0*(1-alpha_B); double f2 = 2.0*alpha_B*(1-alpha_B)/alpha_G; band->G_b *= (float)(f1*f1 + f2*f2); } else if (c == 2) { double f1 = 2.0*(1-alpha_R); double f2 = 2.0*alpha_R*(1-alpha_R)/alpha_G; band->G_b *= (float)(f1*f1 + f2*f2); } } } // Now determine code-block partition parameters for the subband. band->block_partition.pos = res->precinct_partition.pos; band->block_partition.size = tc->blk; if (b != LL_BAND) { band->block_partition.size.x <<= 1; band->block_partition.size.y <<= 1; } band->block_partition &= res->precinct_partition; // Intersect. band->blocks_per_precinct.x = res->precinct_partition.size.x / band->block_partition.size.x; band->blocks_per_precinct.y = res->precinct_partition.size.y / band->block_partition.size.y; if (b != LL_BAND) { band->block_partition.pos.x &= ~(band->band_idx.x); band->block_partition.pos.y &= ~(band->band_idx.y); band->block_partition.size.x >>= 1; band->block_partition.size.y >>= 1; if (!band->block_partition) { kdu_error e; e << "Precinct partition dimensions must " "be >= 2 in all but the lowest resolution level!"; } } check_coding_partition(band->block_partition); band->block_indices = band->region_indices = get_partition_indices(band->block_partition,band->dims); band->log2_blocks_per_precinct = kdu_coords(0,0); while ((1<<band->log2_blocks_per_precinct.x) < band->blocks_per_precinct.x) band->log2_blocks_per_precinct.x++; while ((1<<band->log2_blocks_per_precinct.y) < band->blocks_per_precinct.y) band->log2_blocks_per_precinct.y++; } // End of subband loop. res_dims = get_band_dims(res_dims,kdu_coords(0,0)); } // End of resolution loop. } // End of tile-component loop. // Perform any parameter consistency checks. if (use_ycc) { if ((num_components < 3) || (comps[0].reversible != comps[1].reversible) || (comps[1].reversible != comps[2].reversible) || (comps[0].sub_sampling != comps[1].sub_sampling) || (comps[1].sub_sampling != comps[2].sub_sampling)) { kdu_error e; e << "Illegal colour transform specified when " "image has insufficient or incompatible colour components."; } } // Now set up the packet sequencing machinery. Note that packet // sequencing is performed incrementally, rather than up front. total_packets = total_precincts * num_layers; initialized = true; num_transferred_packets = 0; skipping_to_sop = false; sequencer = new kd_packet_sequencer(this); if (read_failure) finished_reading();}/*****************************************************************************//* kd_tile::open *//*****************************************************************************/void kd_tile::open(){ if (is_open) { kdu_error e; e << "You must close a tile before you can re-open it."; } // Inherit appearance parameters from parent object first_apparent_component = codestream->first_apparent_component; num_apparent_components = codestream->num_apparent_components; num_apparent_layers = codestream->max_apparent_layers; if (num_apparent_layers > num_layers) num_apparent_layers = num_layers; region = dims & codestream->region; // Walk through the components for (int c=0; c < num_components; c++) { kd_tile_comp *tc = comps + c; kdu_coords subs = tc->sub_sampling; kdu_coords min, lim; min = region.pos; lim = min + region.size; min.x = ceil_ratio(min.x,subs.x); lim.x = ceil_ratio(lim.x,subs.x); min.y = ceil_ratio(min.y,subs.y); lim.y = ceil_ratio(lim.y,subs.y); tc->region.pos = min; tc->region.size = lim - min; tc->apparent_dwt_levels = tc->dwt_levels - codestream->discard_levels; if (tc->apparent_dwt_levels < 0) { kdu_error e; e << "Attempting to discard more DWT levels than are " "available in one or more tile components!"; } // Find the DWT kernel lengths for use in mapping regions of interest. kdu_kernels kernels(tc->kernel_id,tc->reversible); int synth_hlen_low, synth_hlen_high; kernels.get_impulse_response(KDU_SYNTHESIS_LOW,synth_hlen_low); kernels.get_impulse_response(KDU_SYNTHESIS_HIGH,synth_hlen_high); // Now work through the resolution levels. kdu_dims next_region = tc->region; for (int r=tc->dwt_levels; r >= 0; r--) { kd_resolution *res = tc->resolutions + r; res->region = next_region & res->dims; for (int b=res->min_band; b <= res->max_band; b++) { kd_subband *band = res->bands + b; if (r > 0) { band->region = get_band_dims(res->region,band->band_idx, synth_hlen_low,synth_hlen_high); band->region &= band->dims; } else band->region = res->region; band->region_indices = get_partition_indices(band->block_partition,band->region); } if (r > tc->apparent_dwt_levels) next_region = get_band_dims(res->region,kdu_coords(0,0)); else next_region = get_band_dims(res->region,kdu_coords(0,0), synth_hlen_low,synth_hlen_high); } } is_open = true; codestream->num_open_tiles++;}/*****************************************************************************//* kd_tile::read_tile_part_header *//*****************************************************************************/bool kd_tile::read_tile_part_header(){ assert(codestream->in != NULL); if (exhausted || ((num_tparts > 0) && (next_tpart >= num_tparts))) return false; do { kd_tile *active = codestream->active_tile; if (active != NULL) { // Read data into tile until we come to an SOT marker. kd_precinct *precinct; while ((precinct=active->sequencer->next_in_sequence()) != NULL) if (!precinct->read_packet()) break; if (precinct == NULL) { // May not have read the next marker yet. codestream->active_tile = NULL; if (codestream->marker->get_code() != KDU_SOT) codestream->marker->read(); } assert(codestream->active_tile == NULL); } if (codestream->in->failed()) return false; if (codestream->marker->get_code() != KDU_SOT) { kdu_error e; e << "Invalid marker code found in code-stream!\n"; e << "\tExpected SOT marker and got "; codestream->marker->print_current_code(e); e << "."; } // Now process the SOT marker. int seg_length = codestream->marker->get_length(); assert(seg_length == 8); // Should already have been checked in `read'. kdu_byte *bp = codestream->marker->get_bytes(); kdu_byte *end = bp+seg_length; int sot_tnum = kdu_read(bp,end,2); int sot_tpart_length = kdu_read(bp,end,4); int sot_tpart = kdu_read(bp,end,1); int sot_num_tparts = kdu_read(bp,end,1); active = codestream->tile_refs[sot_tnum]; if ((active != this) && (sot_tpart_length == 0)) { // At the last tile-part and it belongs to a different tile. finished_reading(); return false; } if (active == NULL) active = codestream->create_tile(sot_tnum); // May call here again else if (active != KD_EXPIRED_TILE) { // Read a new tile-part header for the currently active tile. assert(active->tnum == sot_tnum); if (active->next_tpart != sot_tpart) { kdu_error e; e << "Missing or out-of-sequence tile-parts for " "tile number " << sot_tnum << " in code-stream!"; } if (sot_num_tparts != 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -