diff --git a/src/vw/Plate/Makefile.am b/src/vw/Plate/Makefile.am index 5d37016aa..f5bff4aab 100644 --- a/src/vw/Plate/Makefile.am +++ b/src/vw/Plate/Makefile.am @@ -171,6 +171,9 @@ rpc_tool_LDADD = $(PLATE_LOCAL_LIBS) hirise2tif_SOURCES = hirise2tif.cc hirise2tif_LDADD = @PKG_CARTOGRAPHY_LIBS@ $(PLATE_LOCAL_LIBS) +mipmap_SOURCES = mipmap.cc +mipmap_LDADD = $(PLATE_LOCAL_LIBS) + platecopy_SOURCES = platecopy.cc platecopy_LDADD = $(PLATE_LOCAL_LIBS) @@ -194,6 +197,7 @@ bin_PROGRAMS = \ index_client \ index_perftest \ index_server \ + mipmap \ platecopy \ plate2dem \ platetransform \ diff --git a/src/vw/Plate/PlateManager.cc b/src/vw/Plate/PlateManager.cc index 85e1846c7..e2813b887 100644 --- a/src/vw/Plate/PlateManager.cc +++ b/src/vw/Plate/PlateManager.cc @@ -294,7 +294,7 @@ void PlateManager::slow_mipmap( uint32 output_level, std::list -void PlateManager::fast_mipmap( uint32 starting_output_level, std::list& input_hdrs, bool preblur, const d::RememberCallback& pc) const +void PlateManager::fast_mipmap( uint32 starting_output_level, int32 stopping_level, std::list& input_hdrs, bool preblur, const d::RememberCallback& pc) const { typedef ImageView image_t; level_data scratch1, scratch2; @@ -310,7 +310,7 @@ void PlateManager::fast_mipmap( uint32 starting_output_level, std::list< cache_consume_tiles(*m_platefile, tiles, curr->cache); - for (int32 level = starting_output_level; level >= 0; --level) + for (int32 level = starting_output_level; level >= stopping_level; --level) { std::swap(curr, prev); // point prev at 'current' curr->clear(); // and dump the old 'prev' @@ -338,13 +338,14 @@ template void PlateManager::mipmap(uint32 starting_level, BBox2i const& starting_region, TransactionOrNeg read_transaction_id, bool preblur, - const ProgressCallback &progress_callback) const + const ProgressCallback &progress_callback, + uint32 stopping_level ) const { const uint64 CACHE_TILES = calc_cache_tile_count(); BBox2i input_region(starting_region); - for (int32 output_level = starting_level-1; output_level >= 0; --output_level) + for (int32 output_level = starting_level-1; output_level >= stopping_level; --output_level) { std::list hdrs = m_platefile->search_by_region(output_level+1, input_region, read_transaction_id); size_t hdrs_size = hdrs.size(); @@ -360,7 +361,7 @@ void PlateManager::mipmap(uint32 starting_level, BBox2i const& starting_ else { uint32 remaining_tiles = approximate_total_tiles(input_region, hdrs.size()) - hdrs.size(); vw_out(VerboseDebugMessage, "platefile") << "\nFAST_MIPMAP, level " << output_level << ", tile_count(" << hdrs_size << ") less than " << CACHE_TILES / 2 << "(~" << remaining_tiles << " tiles left)" << std::endl; - fast_mipmap(output_level, hdrs, preblur, d::RememberCallback(progress_callback, float(output_level)/starting_level, remaining_tiles)); + fast_mipmap(output_level, stopping_level, hdrs, preblur, d::RememberCallback(progress_callback, float(output_level)/starting_level, remaining_tiles)); break; } input_region = move_up(input_region); @@ -395,7 +396,8 @@ namespace platefile { PlateManager::mipmap(uint32 starting_level, BBox2i const& bbox, \ TransactionOrNeg transaction_id, \ bool preblur, \ - const ProgressCallback &progress_callback) const; \ + const ProgressCallback &progress_callback, \ + uint32 stopping_level ) const; \ template void \ PlateManager::affected_tiles(BBox2i const& image_size, \ TransformRef const& tx, int tile_size, \ diff --git a/src/vw/Plate/PlateManager.h b/src/vw/Plate/PlateManager.h index f697c48e9..3c4032021 100644 --- a/src/vw/Plate/PlateManager.h +++ b/src/vw/Plate/PlateManager.h @@ -64,8 +64,8 @@ namespace platefile { ImageViewRef& image, TransformRef& txref, int& level ) const = 0; - void slow_mipmap( uint32 level, std::list& src_hdrs, bool preblur, const detail::RememberCallback& pc) const; - void fast_mipmap( uint32 starting_level, std::list& src_hdrs, bool preblur, const detail::RememberCallback& pc) const; + void slow_mipmap( uint32 level, std::list& src_hdrs, bool preblur, const detail::RememberCallback& pc) const; + void fast_mipmap( uint32 starting_level, int32 stopping_level, std::list& src_hdrs, bool preblur, const detail::RememberCallback& pc) const; uint64 calc_cache_tile_count() const; public: @@ -82,7 +82,7 @@ namespace platefile { // tiles. // input_transaction_id -- to use when reading // output_transaction_id -- to use when writing - virtual void mipmap(uint32 starting_level, BBox2i const& bbox, TransactionOrNeg input_transaction_id, bool preblur, const ProgressCallback &progress_callback = ProgressCallback::dummy_instance()) const; + virtual void mipmap(uint32 starting_level, BBox2i const& bbox, TransactionOrNeg input_transaction_id, bool preblur, const ProgressCallback &progress_callback = ProgressCallback::dummy_instance(), uint32 stopping_level=0) const; // Provides user a georeference for a particular level of the pyramid virtual cartography::GeoReference georeference( int level ) const = 0; diff --git a/src/vw/Plate/mipmap.cc b/src/vw/Plate/mipmap.cc new file mode 100644 index 000000000..4b8ef7e5d --- /dev/null +++ b/src/vw/Plate/mipmap.cc @@ -0,0 +1,192 @@ +// __BEGIN_LICENSE__ +// Copyright (C) 2006-2011 United States Government as represented by +// the Administrator of the National Aeronautics and Space Administration. +// All Rights Reserved. +// __END_LICENSE__ + +#include +#include +using namespace vw; +using namespace vw::platefile; + +#include +#include +#include +namespace po = boost::program_options; + +// Mipmap takes the following options +// uint32 level +// BBox2i box +// TransactionOrNeg input_transaction +// bool preblur +// ProgressCallback + +class MipmapParameters { + + void error(std::string arg, std::string const& params) { + vw_out(ErrorMessage) << "Error parsing arguments for --" << arg << " : " << params << "\n"; + exit(1); + } + +public: + int starting_level, stopping_level; + TransactionOrNeg transaction_id; + BBox2i region; + std::string mode; + + MipmapParameters( std::string const& mode, + std::string const& region_string, + std::string const& level_string, + TransactionOrNeg tid ) : + mode(mode), transaction_id(tid) { + + typedef boost::tokenizer > tokenizer; + boost::char_separator sep(",:@"); + + if ( level_string.empty() ) { + this->error("level", level_string); + } else { + tokenizer tokens(level_string, sep); + tokenizer::iterator tok_iter = tokens.begin(); + + if (tok_iter == tokens.end()) this->error("level", level_string); + starting_level = boost::lexical_cast(*tok_iter); + ++tok_iter; + + if (tok_iter == tokens.end()) this->error("level", level_string); + stopping_level = boost::lexical_cast(*tok_iter); + ++tok_iter; + + if (tok_iter != tokens.end()) this->error("level", level_string); + } + + if ( region_string.empty() ) { + region = BBox2i(0, 0, 0x1<error("region", region_string); + region.min()[0] = boost::lexical_cast(*tok_iter); + ++tok_iter; + + if (tok_iter == tokens.end()) this->error("region", region_string); + region.min()[1] = boost::lexical_cast(*tok_iter); + ++tok_iter; + + if (tok_iter == tokens.end()) this->error("region", region_string); + region.max()[0] = boost::lexical_cast(*tok_iter); + ++tok_iter; + + if (tok_iter == tokens.end()) this->error("region", region_string); + region.max()[1] = boost::lexical_cast(*tok_iter); + ++tok_iter; + + if (tok_iter != tokens.end()) this->error("region", region_string); + } + } +}; + +template +void do_mipmap(boost::shared_ptr input_plate, MipmapParameters const& mipmap_params) { + + typedef PlateManager PM; + boost::scoped_ptr pm(PM::make(mipmap_params.mode, input_plate)); + + input_plate->transaction_resume( mipmap_params.transaction_id.promote() ); + input_plate->write_request(); + + pm->mipmap( mipmap_params.starting_level, mipmap_params.region, + mipmap_params.transaction_id, true, + TerminalProgressCallback("plate.tools.mipmap","mipmap:"), + mipmap_params.stopping_level); + + input_plate->write_complete(); + input_plate->transaction_end(true); +} + +int main( int argc, char *argv[] ) { + Url plate_url; + std::string mode, region_string, level_string; + TransactionOrNeg transaction_id; + int level; + bool help; + + po::options_description general_options("\nUtility for mipmapping a transaction ID that exists only on one level"); + general_options.add_options() + ("level-range,l", po::value(&level_string), "where arg = :. Start level is where the data currently resides and stop level is where you want the data to finally be at.") + ("region", po::value(®ion_string), "where arg = ,:,. Optional.") + ("transaction-id,t", po::value(&transaction_id), "transaction ID to request and to write.") + ("mode,m", po::value(&mode), "Output mode [toast, equi, polar]") + ("help,h", po::bool_switch(&help), "Display this help message."); + + po::options_description hidden_options(""); + hidden_options.add_options() + ("url", po::value(&plate_url)); + + po::options_description options("Allowed Options"); + options.add(general_options).add(hidden_options); + + po::positional_options_description p; + p.add("url", 1); + + std::ostringstream usage; + usage << "Usage: " << argv[0] << " [options] ..." < platefile( new PlateFile(plate_url) ); + switch(platefile->pixel_format()) { + case VW_PIXEL_GRAYA: + switch(platefile->channel_type()) { + case VW_CHANNEL_UINT8: + do_mipmap >(platefile, mipmap_params); + break; + case VW_CHANNEL_INT16: + do_mipmap >(platefile, mipmap_params); + break; + case VW_CHANNEL_FLOAT32: + do_mipmap >(platefile, mipmap_params); + break; + default: + vw_throw(ArgumentErr() << "Image contains a channel type not supported by snapshot.\n"); + } + break; + + case VW_PIXEL_RGBA: + switch(platefile->channel_type()) { + case VW_CHANNEL_UINT8: + do_mipmap >(platefile, mipmap_params); + break; + default: + vw_throw(ArgumentErr() << "Image contains a channel type not supported by snapshot.\n"); + } + break; + default: + vw_throw(ArgumentErr() << "Image contains a pixel type not supported by snapshot.\n"); + } + } catch ( const vw::Exception& e ) { + std::cout << "An error occured: " << e.what() << "\nExiting.\n\n"; + return 0; + } + + return 0; +}