Skip to content

Commit

Permalink
Added a mipmap utility to plate
Browse files Browse the repository at this point in the history
This is for use after something like plate-reduce, which creates only
one level.
  • Loading branch information
Zachary Moratto committed Nov 11, 2011
1 parent a46e5e6 commit f2a1316
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 9 deletions.
4 changes: 4 additions & 0 deletions src/vw/Plate/Makefile.am
Expand Up @@ -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)

Expand All @@ -194,6 +197,7 @@ bin_PROGRAMS = \
index_client \
index_perftest \
index_server \
mipmap \
platecopy \
plate2dem \
platetransform \
Expand Down
14 changes: 8 additions & 6 deletions src/vw/Plate/PlateManager.cc
Expand Up @@ -294,7 +294,7 @@ void PlateManager<PixelT>::slow_mipmap( uint32 output_level, std::list<TileHeade
}

template <class PixelT>
void PlateManager<PixelT>::fast_mipmap( uint32 starting_output_level, std::list<TileHeader>& input_hdrs, bool preblur, const d::RememberCallback& pc) const
void PlateManager<PixelT>::fast_mipmap( uint32 starting_output_level, int32 stopping_level, std::list<TileHeader>& input_hdrs, bool preblur, const d::RememberCallback& pc) const
{
typedef ImageView<PixelT> image_t;
level_data<PixelT> scratch1, scratch2;
Expand All @@ -310,7 +310,7 @@ void PlateManager<PixelT>::fast_mipmap( uint32 starting_output_level, std::list<

cache_consume_tiles<PixelT>(*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'
Expand Down Expand Up @@ -338,13 +338,14 @@ template <class PixelT>
void PlateManager<PixelT>::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<TileHeader> hdrs = m_platefile->search_by_region(output_level+1, input_region, read_transaction_id);
size_t hdrs_size = hdrs.size();
Expand All @@ -360,7 +361,7 @@ void PlateManager<PixelT>::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);
Expand Down Expand Up @@ -395,7 +396,8 @@ namespace platefile {
PlateManager<PIXELT >::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<PIXELT >::affected_tiles(BBox2i const& image_size, \
TransformRef const& tx, int tile_size, \
Expand Down
6 changes: 3 additions & 3 deletions src/vw/Plate/PlateManager.h
Expand Up @@ -64,8 +64,8 @@ namespace platefile {
ImageViewRef<PixelT>& image,
TransformRef& txref, int& level ) const = 0;

void slow_mipmap( uint32 level, std::list<TileHeader>& src_hdrs, bool preblur, const detail::RememberCallback& pc) const;
void fast_mipmap( uint32 starting_level, std::list<TileHeader>& src_hdrs, bool preblur, const detail::RememberCallback& pc) const;
void slow_mipmap( uint32 level, std::list<TileHeader>& src_hdrs, bool preblur, const detail::RememberCallback& pc) const;
void fast_mipmap( uint32 starting_level, int32 stopping_level, std::list<TileHeader>& src_hdrs, bool preblur, const detail::RememberCallback& pc) const;
uint64 calc_cache_tile_count() const;

public:
Expand All @@ -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;
Expand Down
192 changes: 192 additions & 0 deletions 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 <vw/Plate/PlateFile.h>
#include <vw/Plate/PlateManager.h>
using namespace vw;
using namespace vw::platefile;

#include <boost/tokenizer.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/program_options.hpp>
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<boost::char_separator<char> > tokenizer;
boost::char_separator<char> 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<int>(*tok_iter);
++tok_iter;

if (tok_iter == tokens.end()) this->error("level", level_string);
stopping_level = boost::lexical_cast<int>(*tok_iter);
++tok_iter;

if (tok_iter != tokens.end()) this->error("level", level_string);
}

if ( region_string.empty() ) {
region = BBox2i(0, 0, 0x1<<starting_level, 0x1<<starting_level);
} else {
tokenizer tokens(region_string, sep);
tokenizer::iterator tok_iter = tokens.begin();

if (tok_iter == tokens.end()) this->error("region", region_string);
region.min()[0] = boost::lexical_cast<int>(*tok_iter);
++tok_iter;

if (tok_iter == tokens.end()) this->error("region", region_string);
region.min()[1] = boost::lexical_cast<int>(*tok_iter);
++tok_iter;

if (tok_iter == tokens.end()) this->error("region", region_string);
region.max()[0] = boost::lexical_cast<int>(*tok_iter);
++tok_iter;

if (tok_iter == tokens.end()) this->error("region", region_string);
region.max()[1] = boost::lexical_cast<int>(*tok_iter);
++tok_iter;

if (tok_iter != tokens.end()) this->error("region", region_string);
}
}
};

template <class PixelT>
void do_mipmap(boost::shared_ptr<PlateFile> input_plate, MipmapParameters const& mipmap_params) {

typedef PlateManager<PixelT> PM;
boost::scoped_ptr<PM> 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>:<stop level>. Start level is where the data currently resides and stop level is where you want the data to finally be at.")
("region", po::value(&region_string), "where arg = <ul_x>,<ul_y>:<lr_x>,<lr_y>. 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] <filename>..." <<std::endl << std::endl;
usage << general_options << std::endl;

try {
po::variables_map vm;
po::store( po::command_line_parser( argc, argv ).options(options).positional(p).run(), vm );
po::notify( vm );
} catch (const po::error& e ) {
vw_out() << usage.str() << std::endl
<< "Failed to parse command line arguments:" << std::endl
<< "\t" << e.what() << std::endl;
return 1;
}

if ( help || plate_url == Url() ) {
vw_out() << usage.str() << "\n";;
return 1;
}

MipmapParameters mipmap_params(mode, region_string, level_string, transaction_id);

try {
boost::shared_ptr<PlateFile> platefile( new PlateFile(plate_url) );
switch(platefile->pixel_format()) {
case VW_PIXEL_GRAYA:
switch(platefile->channel_type()) {
case VW_CHANNEL_UINT8:
do_mipmap<PixelGrayA<uint8> >(platefile, mipmap_params);
break;
case VW_CHANNEL_INT16:
do_mipmap<PixelGrayA<int16> >(platefile, mipmap_params);
break;
case VW_CHANNEL_FLOAT32:
do_mipmap<PixelGrayA<float32> >(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<PixelRGBA<uint8> >(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;
}

0 comments on commit f2a1316

Please sign in to comment.