📄 kdu_compress.cpp
字号:
kdc_flow_control::advance_components(){ bool found_line=false; while (!found_line) { bool all_done = true; for (int n=0; n < num_components; n++) { kdc_component_flow_control *comp = components + n; assert(comp->ratio_counter >= 0); if (comp->remaining_lines > 0) { all_done = false; comp->ratio_counter -= count_delta; if (comp->ratio_counter < 0) { found_line = true; if (comp->reader.exists() && comp->line.get_width()) comp->reader.get(n,comp->line,x_tnum); } } } if (all_done) return false; } return true;}/*****************************************************************************//* kdc_flow_control::access_compressor_line *//*****************************************************************************/kdu_line_buf * kdc_flow_control::access_compressor_line(int comp_idx){ assert((comp_idx >= 0) && (comp_idx < num_components)); kdc_component_flow_control *comp = components + comp_idx; return (comp->ratio_counter < 0)?(&(comp->line)):NULL;}/*****************************************************************************//* kdc_flow_control::process_components *//*****************************************************************************/void kdc_flow_control::process_components(){ if ((use_ycc) && (components[0].ratio_counter < 0)) { assert((num_components >= 3) && (components[1].ratio_counter < 0) && (components[2].ratio_counter < 0)); kdu_convert_rgb_to_ycc(components[0].line, components[1].line, components[2].line); } for (int n=0; n < num_components; n++) { kdc_component_flow_control *comp = components + n; if (comp->ratio_counter < 0) { comp->ratio_counter += comp->vert_subsampling; assert(comp->ratio_counter >= 0); assert(comp->remaining_lines > 0); comp->remaining_lines--; comp->compressor.push(comp->line,true); } }}/*****************************************************************************//* kdc_flow_control::advance_tile *//*****************************************************************************/bool kdc_flow_control::advance_tile(){ int n; if (!tile) return false; for (n=0; n < num_components; n++) { kdc_component_flow_control *comp = components + n; assert(comp->remaining_lines == 0); assert(comp->compressor.exists()); comp->compressor.destroy(); comp->line.destroy(); } tile.close(); tile = kdu_tile(NULL); tile_idx.y++; if ((tile_idx.y-valid_tile_indices.pos.y) == valid_tile_indices.size.y) return false; // Prepare for processing the next vertical tile. tile = codestream.open_tile(tile_idx); for (n=0; n < num_components; n++) { kdc_component_flow_control *comp = components + n; kdu_tile_comp tc = tile.access_component(n); comp->reversible = tc.get_reversible(); kdu_resolution res = tc.access_resolution(); kdu_dims dims; res.get_dims(dims); comp->allocator.restart(); bool use_shorts = (tc.get_bit_depth(true)>16)?false:(comp->allow_shorts); comp->line.pre_create(&(comp->allocator),dims.size.x, comp->reversible,use_shorts); kdu_roi_node *roi_node = NULL; if (roi_image != NULL) roi_node = roi_image->acquire_node(n,dims); if (res.which() == 0) comp->compressor = kdu_encoder(res.access_subband(LL_BAND),&(comp->allocator), use_shorts,1.0F,roi_node); else comp->compressor = kdu_analysis(res,&(comp->allocator),use_shorts,1.0F,roi_node); comp->allocator.finalize(); comp->line.create(); comp->ratio_counter = 0; comp->remaining_lines = dims.size.y; } use_ycc = tile.get_ycc(); if (use_ycc) assert((num_components >= 3) && (components[0].reversible == components[1].reversible) && (components[1].reversible == components[2].reversible)); return true;}/* ========================================================================= *//* External Functions *//* ========================================================================= *//*****************************************************************************//* main *//*****************************************************************************/int main(int argc, char *argv[]){ kdu_customize_warnings(&std::cout); kdu_customize_errors(&std::cerr); kdu_args args(argc,argv,"-s"); // Collect simple arguments. bool transpose, vflip, hflip; bool allow_rate_prediction, allow_shorts, mem, quiet, no_weights, no_palette; int cpu_iterations; char *ofname; std::ostream *record_stream; kdc_file_binding *inputs = parse_simple_args(args,ofname,record_stream,transpose,vflip,hflip, allow_rate_prediction,allow_shorts,no_weights, no_palette,cpu_iterations,mem,quiet); // Create appropriate output file. kdu_compressed_target *output = NULL; kdu_simple_file_target file_out; jp2_target jp2_out; if (check_jp2_suffix(ofname)) { output = &jp2_out; jp2_out.open(ofname); } else { output = &file_out; file_out.open(ofname); } // Collects any parameters required for raw input. siz_params siz; char *string; for (string=args.get_first(); string != NULL; ) string = args.advance(siz.parse_string(string)); // Set up input image files. kdu_rgb8_palette palette; // To support palettized imagery. kdc_file_binding *iscan; int num_components; bool extra_flip=false; num_components = 0; for (iscan=inputs; iscan != NULL; iscan=iscan->next) { bool flip; iscan->first_comp_idx = num_components; iscan->reader = kdu_image_in(iscan->fname,&siz,num_components,flip, ((no_palette || !jp2_out)?NULL:(&palette))); iscan->num_components = num_components - iscan->first_comp_idx; if (iscan == inputs) extra_flip = flip; if (extra_flip != flip) { kdu_error e; e << "Cannot mix input file types which have different " "vertical ordering conventions (i.e., top-to-bottom and " "bottom-to-top)."; } } if (extra_flip) vflip = !vflip; siz.set(Scomponents,0,0,num_components); // Complete `siz' object. siz_params *siz_p = &siz; siz_p->finalize(); // Access func via v-table siz_params transformed_siz; // Use this one to construct code-stream. transformed_siz.copy_from(&siz,-1,-1,-1,0,0,transpose,false,false); if (jp2_out.exists()) set_jp2_attributes(jp2_out,&transformed_siz,palette,num_components,args); // Construct the `kdu_codestream' object and parse all remaining arguments. kdu_codestream codestream; codestream.create(&transformed_siz,output); for (string=args.get_first(); string != NULL; ) string = args.advance(codestream.access_siz()->parse_string(string)); if (jp2_out.exists()) set_jp2_coding_defaults(jp2_out,codestream.access_siz()); int num_layer_specs = 0; int *layer_bytes = assign_layer_bytes(args,codestream.access_siz(),num_layer_specs); kdu_uint16 *layer_thresholds = assign_layer_thresholds(args,num_layer_specs); if ((num_layer_specs > 0) && allow_rate_prediction && (layer_bytes[num_layer_specs-1] > 0)) codestream.set_max_bytes(layer_bytes[num_layer_specs-1]); if ((num_layer_specs > 0) && allow_rate_prediction && (layer_thresholds[num_layer_specs-1] > 0)) codestream.set_min_slope_threshold(layer_thresholds[num_layer_specs-1]); if ((num_layer_specs < 2) && !quiet) pretty_cout << "Note:\n\tIf you want quality scalability, you should " "generate multiple layers with `-rate' or by using " "the \"Clayers\" option.\n"; if ((num_components == 3) && (!no_weights)) set_default_colour_weights(codestream.access_siz(),quiet); codestream.access_siz()->finalize_all(); codestream.set_textualization(record_stream); if (cpu_iterations >= 0) codestream.collect_timing_stats(cpu_iterations); codestream.change_appearance(transpose,vflip,hflip); kdu_roi_image *roi_source = create_roi_source(codestream,args); if (args.show_unrecognized(pretty_cout) != 0) { kdu_error e; e << "There were unrecognized command line arguments!"; } // Now we are ready for sample data processing. int x_tnum; kdu_dims tile_indices; codestream.get_valid_tiles(tile_indices); kdc_flow_control **tile_flows = new kdc_flow_control *[tile_indices.size.x]; for (x_tnum=0; x_tnum < tile_indices.size.x; x_tnum++) tile_flows[x_tnum] = new kdc_flow_control(inputs,codestream,x_tnum,allow_shorts,roi_source); bool done = false; while (!done) { while (!done) { // Process a row of tiles line by line. done = true; for (x_tnum=0; x_tnum < tile_indices.size.x; x_tnum++) { if (tile_flows[x_tnum]->advance_components()) { done = false; tile_flows[x_tnum]->process_components(); } } } for (x_tnum=0; x_tnum < tile_indices.size.x; x_tnum++) if (tile_flows[x_tnum]->advance_tile()) done = false; } int sample_bytes = 0; for (x_tnum=0; x_tnum < tile_indices.size.x; x_tnum++) { sample_bytes += tile_flows[x_tnum]->get_buffer_memory(); delete tile_flows[x_tnum]; } delete tile_flows; // Produce the compressed output. codestream.flush(layer_bytes,num_layer_specs,layer_thresholds); // Cleanup if (cpu_iterations >= 0) { int num_samples; double seconds = codestream.get_timing_stats(&num_samples); pretty_cout << "End-to-end CPU time "; if (cpu_iterations > 0) pretty_cout << "(estimated) "; pretty_cout << "= " << seconds << " seconds (" << 1.0E6*seconds/num_samples << " us/sample)\n"; } if (cpu_iterations > 0) { int num_samples; double seconds = codestream.get_timing_stats(&num_samples,true); if (seconds > 0.0) { pretty_cout << "Block encoding CPU time (estimated) "; pretty_cout << "= " << seconds << " seconds (" << 1.0E6*seconds/num_samples << " us/sample)\n"; } } if (mem) { pretty_cout << "\nSample processing/buffering memory = " << sample_bytes << " bytes.\n"; pretty_cout << "Compressed data memory = " << codestream.get_compressed_data_memory() << " bytes.\n"; pretty_cout << "State memory associated with compressed data = " << codestream.get_compressed_state_memory() << " bytes.\n"; } if (!quiet) { double bpp_dims = get_bpp_dims(codestream.access_siz()); pretty_cout << "\nGenerated " << codestream.get_num_tparts() << " tile-part(s) for a total of " << tile_indices.area() << " tile(s).\n"; pretty_cout << "Code-stream bytes (excluding any file " "format) = " << codestream.get_total_bytes() << " = " << 8.0*codestream.get_total_bytes() / bpp_dims << " bits/pel.\n"; int layer_idx; pretty_cout << "Layer bit-rates (possibly inexact if tiles are " "divided across tile-parts):\n\t\t"; for (layer_idx=0; layer_idx < num_layer_specs; layer_idx++) { if (layer_idx > 0) pretty_cout << ", "; pretty_cout << 8.0*layer_bytes[layer_idx]/bpp_dims; } pretty_cout << "\n"; pretty_cout << "Layer thresholds:\n\t\t"; for (layer_idx=0; layer_idx < num_layer_specs; layer_idx++) { if (layer_idx > 0) pretty_cout << ", "; pretty_cout << (int)(layer_thresholds[layer_idx]); } pretty_cout << "\n"; } delete[] layer_bytes; delete[] layer_thresholds; codestream.destroy(); output->close(); if (roi_source != NULL) delete roi_source; if (record_stream != NULL) delete record_stream; delete inputs; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -