📄 kdu_transcode.cpp
字号:
*dp = *sp; sp += row_gap_in; dp += out_cinc; *dp = *sp; sp += row_gap_in; dp += out_cinc; } while (c--) { *dp = *sp; sp += row_gap_in; dp += out_cinc; } } } if ((out->num_passes % 3) != 1) { /* Round up to the next whole bit-plane to avoid any degradation from further geometric transformations. */ for (; (out->num_passes % 3) != 1; out->num_passes++) { out->pass_slopes[out->num_passes] = out->pass_slopes[out->num_passes-1]; out->pass_slopes[out->num_passes-1] = 0; } dp = out->sample_buffer; // Prepare to reset rounding bit int p = 30 - out->missing_msbs - (out->num_passes / 3); kdu_int32 mask = (((kdu_int32)(-1))<<p); for (c=num_samples; c > 3; c-=4, dp+=4) { if ((dp[0] & mask) == 0) dp[0] &= (mask+mask); if ((dp[1] & mask) == 0) dp[1] &= (mask+mask); if ((dp[2] & mask) == 0) dp[2] &= (mask+mask); if ((dp[3] & mask) == 0) dp[3] &= (mask+mask); } for (; c > 0; c--, dp++) if ((dp[0] & mask) == 0) dp[0] &= (mask+mask); } } else { // No change in the sample data itself. memcpy(out->sample_buffer,in->sample_buffer, (size_t) num_samples * sizeof(kdu_int32)); } kdu_block_encoder encoder; encoder.encode(out); } else { // Just copy compressed code-bytes. No need for block transcoding. if (out->max_bytes < num_bytes) out->set_max_bytes(num_bytes,false); memcpy(out->byte_buffer,in->byte_buffer,(size_t) num_bytes); }}/*****************************************************************************//* STATIC copy_tile *//*****************************************************************************/static void copy_tile(kdu_tile tile_in, kdu_tile tile_out, int tnum_in, int tnum_out, kdu_params *siz_in, kdu_params *siz_out, int skip_components, int &num_blocks) /* Although there could be more efficient ways of doing this (in terms of saving memory), we currently just walk through all code-blocks in the most obvious order, copying them from the input to the output tile. Note that the main tile-header coding parameters should have been copied already, but this function will copy POC parameters for non-initial tile-parts, wherever the information has not already been substituted for the purpose of rearranging the packet sequence during transcoding. */{ int num_components = tile_out.get_num_components(); int new_tpart=0, next_tpart = 1; for (int c=0; c < num_components; c++) { kdu_tile_comp comp_in; comp_in = tile_in.access_component(c); kdu_tile_comp comp_out; comp_out = tile_out.access_component(c); int num_resolutions = comp_out.get_num_resolutions(); for (int r=0; r < num_resolutions; r++) { kdu_resolution res_in; res_in = comp_in.access_resolution(r); kdu_resolution res_out; res_out = comp_out.access_resolution(r); int min_band = (r==0)?0:1; int max_band = (r==0)?0:3; for (int b=min_band; b <= max_band; b++) { kdu_subband band_in; band_in = res_in.access_subband(b); kdu_subband band_out; band_out = res_out.access_subband(b); kdu_dims blocks_in; band_in.get_valid_blocks(blocks_in); kdu_dims blocks_out; band_out.get_valid_blocks(blocks_out); if ((blocks_in.size.x != blocks_out.size.x) || (blocks_in.size.y != blocks_out.size.y)) { kdu_error e; e << "Transcoding operation cannot proceed: " "Code-block partitions for the input and output " "code-streams do not agree."; } kdu_coords idx; for (idx.y=0; idx.y < blocks_out.size.y; idx.y++) for (idx.x=0; idx.x < blocks_out.size.x; idx.x++) { kdu_block *in = band_in.open_block(idx+blocks_in.pos,&new_tpart); for (; next_tpart <= new_tpart; next_tpart++) siz_out->copy_from(siz_in,tnum_in,tnum_out,next_tpart, skip_components); kdu_block *out = band_out.open_block(idx+blocks_out.pos); copy_block(in,out); band_in.close_block(in); band_out.close_block(out); num_blocks++; } } } }}/*****************************************************************************//* EXTERN 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. char *ifname, *ofname; std::ostream *record_stream; int discard_levels; int skip_components, max_components; float max_bpp; bool transpose, vflip, hflip; bool mem, quiet; parse_simple_args(args,ifname,ofname,record_stream, discard_levels,skip_components,max_components,max_bpp, transpose,vflip,hflip,mem,quiet); // Create the input codestream object. kdu_compressed_source *input = NULL; kdu_simple_file_source file_in; jp2_source jp2_in; if (check_jp2_compatible_suffix(ifname)) { input = &jp2_in; jp2_in.open(ifname); } else { input = &file_in; file_in.open(ifname); } kdu_codestream codestream_in; codestream_in.create(input); set_error_behaviour(args,codestream_in); codestream_in.apply_input_restrictions(skip_components,max_components, discard_levels,0,NULL); codestream_in.change_appearance(transpose,vflip,hflip); siz_params *siz_in = codestream_in.access_siz(); // Create the output codestream object. if (check_jp2_compatible_suffix(ofname)) { kdu_error e; e << "Transcoder can reads JP2 files, but currently only " "writes raw code-stream files. You should be able to easily add such " "capability yourself if you really need it."; } kdu_simple_file_target output; output.open(ofname); siz_params siz; siz.copy_from(siz_in,-1,-1,-1,skip_components,discard_levels, transpose,vflip,hflip); siz.set(Scomponents,0,0,codestream_in.get_num_components()); kdu_codestream codestream_out; codestream_out.create(&siz,&output); codestream_out.share_buffering(codestream_in); siz_params *siz_out = codestream_out.access_siz(); siz_out->copy_from(siz_in,-1,-1,-1,skip_components,discard_levels, transpose,vflip,hflip); char *string; for (string=args.get_first(); string != NULL; ) string = args.advance(siz_out->parse_string(string,-1)); codestream_out.access_siz()->finalize_all(-1); codestream_out.set_textualization(record_stream); check_parameter_args(args); // Now ready to perform the transfer of compressed data between streams kdu_dims tile_indices_in; codestream_in.get_valid_tiles(tile_indices_in); kdu_dims tile_indices_out; codestream_out.get_valid_tiles(tile_indices_out); assert((tile_indices_in.size.x == tile_indices_out.size.x) && (tile_indices_in.size.y == tile_indices_out.size.y)); int num_blocks=0; kdu_coords idx; for (idx.y=0; idx.y < tile_indices_out.size.y; idx.y++) for (idx.x=0; idx.x < tile_indices_out.size.x; idx.x++) { kdu_tile tile_in = codestream_in.open_tile(idx+tile_indices_in.pos); int tnum_in = tile_in.get_tnum(); int tnum_out = idx.x + idx.y*tile_indices_out.size.x; siz_out->copy_from(siz_in,tnum_in,tnum_out,0,skip_components, discard_levels,transpose,vflip,hflip); for (string=args.get_first(); string != NULL; ) string = args.advance(siz_out->parse_string(string,tnum_out)); siz_out->finalize_all(tnum_out); /* Note carefully: we must not open the output tile without first copying any tile-specific code-stream parameters, as above. It is tempting to do this. */ kdu_tile tile_out = codestream_out.open_tile(idx+tile_indices_out.pos); assert(tnum_out == tile_out.get_tnum()); copy_tile(tile_in,tile_out,tnum_in,tnum_out,siz_in,siz_out, skip_components,num_blocks); } /* Leave argument warnings to this point, because we need to be able to parse arguments incrementally as tiles become available. */ if (args.show_unrecognized(pretty_cout) != 0) { kdu_error e; e << "There were unrecognized command line arguments!"; } // Generate the output code-stream int max_bytes = INT_MAX; if (max_bpp > 0.0F) max_bytes = (int)(0.125*max_bpp*get_bpp_dims(siz_out)); int non_empty_layers = codestream_out.trans_out(max_bytes); kdu_params *cod = siz_out->access_cluster(COD_params); int total_layers; cod->get(Clayers,0,0,total_layers); if (non_empty_layers > total_layers) non_empty_layers = total_layers; // Can happen if a tile has more layers // Cleanup if (mem) { pretty_cout << "Total compressed data memory = " << codestream_out.get_compressed_data_memory() << " bytes.\n"; pretty_cout << "Total state memory associated with compressed data = " << codestream_in.get_compressed_state_memory() + codestream_out.get_compressed_state_memory() << " bytes.\n"; } if (!quiet) { pretty_cout << "\nOutput contains " << total_layers << " quality layers"; if (non_empty_layers < total_layers) pretty_cout << " (" << total_layers-non_empty_layers << " of these were assigned empty packets)\n"; else pretty_cout << "\n"; pretty_cout << "Transferred " << num_blocks << " code-blocks.\n"; pretty_cout << "\nRead " << codestream_in.get_num_tparts() << " tile-part(s) from a total of " << tile_indices_in.area() << " tile(s).\n"; pretty_cout << "Total bytes read = " << codestream_in.get_total_bytes() << " = " << 8.0*codestream_in.get_total_bytes() / get_bpp_dims(codestream_in.access_siz()) << " bits/pel.\n"; pretty_cout << "\nWrote " << codestream_out.get_num_tparts() << " tile-part(s) in a total of " << tile_indices_out.area() << " tile(s).\n"; pretty_cout << "Total bytes written = " << codestream_out.get_total_bytes() << " = " << 8.0*codestream_out.get_total_bytes() / get_bpp_dims(codestream_out.access_siz()) << " bits/pel.\n"; } codestream_out.destroy(); codestream_in.destroy(); input->close(); if (record_stream != NULL) delete record_stream; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -