📄 kdu_expand.cpp
字号:
kdu_sample16 *dp = chnl->line.get_buf16(); int i = chnl->width; if (comp->line.get_buf16() != NULL) { kdu_sample16 *sp = comp->line.get_buf16(); for (; i > 0; i--, sp++, dp++) *dp = lut[sp->ival]; } else { kdu_sample32 *sp = comp->line.get_buf32(); for (; i > 0; i--, sp++, dp++) *dp = lut[sp->ival]; } } } return true;}/*****************************************************************************//* kde_flow_control::access_decompressed_line *//*****************************************************************************/kdu_line_buf * kde_flow_control::access_decompressed_line(int channel_idx){ assert((channel_idx >= 0) && (channel_idx < num_channels)); kde_channel *chnl = channels + channel_idx; kde_component_flow_control *comp = chnl->source_component; if (comp->ratio_counter >= 0) return NULL; if (chnl->lut != NULL) return &(chnl->line); else return &(comp->line);}/*****************************************************************************//* kde_flow_control::process_components *//*****************************************************************************/void kde_flow_control::process_components(){ for (int c=0; c < num_channels; c++) { kde_channel *chnl = channels + c; kde_component_flow_control *comp = chnl->source_component; if ((comp->ratio_counter < 0) && chnl->writer.exists() && chnl->width) { if (chnl->lut != NULL) chnl->writer.put(c,chnl->line,x_tnum); else chnl->writer.put(c,comp->line,x_tnum); } } for (int n=0; n < num_components; n++) { kde_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--; } }}/*****************************************************************************//* kde_flow_control::advance_tile *//*****************************************************************************/bool kde_flow_control::advance_tile(){ int c; if (!tile) return false; // Clean up existing resources for (c=0; c < num_components; c++) { kde_component_flow_control *comp = components + c; if (!comp->mapped_by_channel) continue; assert(comp->remaining_lines == 0); assert(comp->decompressor.exists()); comp->decompressor.destroy(); comp->line.destroy(); } for (c=0; c < num_channels; c++) { kde_channel *chnl = channels + c; chnl->line.destroy(); } // Advance to next vertical tile. 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; tile = codestream.open_tile(tile_idx); // Prepare for processing the new tile. use_ycc = tile.get_ycc(); for (c=0; c < num_components; c++) { kde_component_flow_control *comp = components + c; comp->tc = tile.access_component(c); comp->res = comp->tc.access_resolution(); comp->reversible = comp->tc.get_reversible(); if (!comp->mapped_by_channel) continue; kdu_dims dims; comp->res.get_dims(dims); comp->ratio_counter = 0; comp->remaining_lines = dims.size.y; comp->allocator.restart(); bool use_shorts = comp->allow_shorts; if ((comp->tc.get_bit_depth(true) > 16) && ((comp->palette_bits == 0) || comp->reversible)) use_shorts = false; comp->line.pre_create(&(comp->allocator),comp->width, comp->reversible,use_shorts); if (comp->res.which() == 0) comp->decompressor = kdu_decoder(comp->res.access_subband(LL_BAND), &(comp->allocator),use_shorts); else comp->decompressor = kdu_synthesis(comp->res, &(comp->allocator),use_shorts); } for (c=0; c < num_channels; c++) if (channels[c].lut != NULL) { if (use_ycc && ((channels[c].source_component - components) < 3)) { kdu_error e; e << "It is illegal for a JP2 file to identify a " "code-stream component as index to a Palette lookup table, if the " "component is also part of a code-stream colour transform (RCT " "or ICT)."; } channels[c].line.pre_create(channels[c].allocator, channels[c].width,false,true); } // Turn off colour transforms if we only want a subset of the components if (!(components[0].mapped_by_channel && components[1].mapped_by_channel && components[2].mapped_by_channel)) use_ycc = false; // Finalize resources for (c=0; c < num_components; c++) if (components[c].mapped_by_channel) { components[c].allocator.finalize(); components[c].line.create(); } for (c=0; c < num_channels; c++) channels[c].line.create(); // Does no harm if not pre-created. 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, allow_shorts, mem, quiet; char *ifname; std::ostream *record_stream; float max_bpp; bool raw_components; int skip_components, discard_levels, cpu_iterations; kde_file_binding *outputs = parse_simple_args(args,ifname,record_stream,max_bpp, transpose,vflip,hflip,allow_shorts, skip_components,raw_components,discard_levels, cpu_iterations,mem,quiet); // Create appropriate input file. kdu_compressed_source *input = NULL; kdu_simple_file_source file_in; jp2_source jp2_in; jp2_channels channels; jp2_palette palette; if (check_jp2_compatible_suffix(ifname)) { if (skip_components & !raw_components) { kdu_error e; e << "The `-skip_components' argument may be " "used only with raw code-stream sources or with the " "`-raw_components' switch."; } input = &jp2_in; jp2_in.open(ifname); if (!raw_components) { channels = jp2_in.access_channels(); palette = jp2_in.access_palette(); } } else { input = &file_in; file_in.open(ifname); raw_components = true; } // Create the codestream object. kdu_codestream codestream; codestream.create(input); set_error_behaviour(args,codestream); if (cpu_iterations >= 0) codestream.collect_timing_stats(cpu_iterations); if (max_bpp > 0.0F) codestream.set_max_bytes((int)(0.125*max_bpp* get_bpp_dims(codestream.access_siz()))); codestream.set_textualization(record_stream); kdu_dims region; set_region_of_interest(args,region,codestream.access_siz()); codestream.apply_input_restrictions(skip_components,0,discard_levels,0, ®ion); codestream.change_appearance(transpose,vflip,hflip); if (args.show_unrecognized(pretty_cout) != 0) { kdu_error e; e << "There were unrecognized command line arguments!"; } // Get the component (or mapped colour channel) dimensional properties kdu_image_dims idims; int n, num_channels, num_components = codestream.get_num_components(); if (channels.exists()) num_channels = channels.get_num_colours(); else num_channels = num_components; for (n=0; n < num_channels; n++) { kdu_dims dims; int precision; bool is_signed; int cmp = n, plt=-1; if (channels.exists()) channels.get_colour_mapping(n,cmp,plt); codestream.get_dims(cmp,dims); if (plt < 0) { precision = codestream.get_bit_depth(cmp); is_signed = codestream.get_signed(cmp); } else { precision = palette.get_bit_depth(plt); is_signed = palette.get_signed(plt); } idims.add_component(dims.size.y,dims.size.x,precision,is_signed); } // Now we are ready to open the output files. kde_file_binding *oscan; bool extra_flip = false; int output_channels=0; for (oscan=outputs; oscan != NULL; oscan=oscan->next) { bool flip; oscan->first_channel_idx = output_channels; oscan->writer = kdu_image_out(oscan->fname,idims,output_channels,flip); oscan->num_channels = output_channels - oscan->first_channel_idx; if (oscan == outputs) extra_flip = flip; if (extra_flip != flip) { kdu_error e; e << "Cannot mix output file types which have " "different vertical ordering conventions (i.e., top-to-bottom and " "bottom-to-top)."; } } if (extra_flip) { vflip = !vflip; codestream.change_appearance(transpose,vflip,hflip); } if (output_channels == 0) output_channels = num_channels; // There may be no output files specified. // The following call saves us the cost of buffering up unused image // components, but not when working with the JP2 file format, for simplicity. codestream.apply_input_restrictions(skip_components, ((jp2_in.exists())?0:output_channels),discard_levels,0,®ion); // Now we are ready for sample data processing. int x_tnum; kdu_dims tile_indices; codestream.get_valid_tiles(tile_indices); kde_flow_control **tile_flows = new kde_flow_control *[tile_indices.size.x]; for (x_tnum=0; x_tnum < tile_indices.size.x; x_tnum++) tile_flows[x_tnum] = new kde_flow_control(outputs,output_channels,codestream, x_tnum,allow_shorts,channels,palette); 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; // 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 decoding 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) { pretty_cout << "\nConsumed " << codestream.get_num_tparts() << " tile-part(s) from 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() / get_bpp_dims(codestream.access_siz()) << " bits/pel.\n"; } codestream.destroy(); input->close(); if (record_stream != NULL) delete record_stream; delete outputs; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -