Skip to content

Commit

Permalink
Improved support for .BIL files and avoid using pointers to DiskImage…
Browse files Browse the repository at this point in the history
…Resource
  • Loading branch information
oleg-alexandrov committed Jul 22, 2017
1 parent bf65c5f commit 06fac3d
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 10 deletions.
2 changes: 1 addition & 1 deletion graveyard/gui/MainWidget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ void imageData::read(std::string const& image, bool ignore_georef,
else
bbox = bounding_box(img); // pixel box

boost::shared_ptr<DiskImageResource> rsrc(DiskImageResource::open(name));
boost::shared_ptr<DiskImageResource> rsrc(DiskImageResourcePtr(name));
nodata_val = -FLT_MAX;
if ( rsrc->has_nodata_read() ) {
nodata_val = rsrc->nodata_read();
Expand Down
2 changes: 1 addition & 1 deletion src/vw/Cartography/GeoReference.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ namespace cartography {
// No image with a SPOT5 suffix can ever have georeference.
if (vw::has_spot5_extension(filename)) return false;

boost::scoped_ptr<DiskImageResource> r(DiskImageResource::open( filename ));
boost::shared_ptr<DiskImageResource> r(DiskImageResourcePtr( filename ));
bool result = read_georeference( georef, *r );

return result;
Expand Down
5 changes: 5 additions & 0 deletions src/vw/FileIO/DiskImageResource.cc
Original file line number Diff line number Diff line change
Expand Up @@ -274,3 +274,8 @@ vw::ImageFormat vw::image_format(const std::string& filename) {
boost::scoped_ptr<vw::SrcImageResource> src(vw::DiskImageResource::open(filename));
return src->format();
}

// Return a smart pointer, this is easier to manage
boost::shared_ptr<vw::DiskImageResource> vw::DiskImageResourcePtr(std::string const& image_file){
return boost::shared_ptr<vw::DiskImageResource>(vw::DiskImageResource::open(image_file));
}
3 changes: 3 additions & 0 deletions src/vw/FileIO/DiskImageResource.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ namespace vw {

ImageFormat image_format(const std::string& filename);

// Return a smart pointer, this is easier to manage
boost::shared_ptr<DiskImageResource> DiskImageResourcePtr(std::string const& image_file);

} // namespace vw

#endif // __VW_FILEIO_DISKIMAGERESOURCE_H__
134 changes: 134 additions & 0 deletions src/vw/FileIO/DiskImageResourceRaw.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,154 @@

#include <boost/smart_ptr/scoped_array.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem.hpp>

using std::fstream;
using std::ifstream;
using std::ofstream;


namespace fs = boost::filesystem;

namespace vw {

// Private local functions
namespace {

// Try to find a .DIM file for the given .BIL file.
std::string DIM_lookup(std::string const& image_file){

// Try replacing the extension with .DIM
std::string cam_file = fs::path(image_file).replace_extension(".DIM").string();
if (fs::exists(cam_file)) return cam_file;

// Now try .dim
cam_file = fs::path(image_file).replace_extension(".dim").string();
if (fs::exists(cam_file)) return cam_file;

// Now try something more complicated. From
// back/SEGMT01/IMAGERY.BIL go to back/SEGMT01/METADATA_BACK.DIM or
// back/SEGMT01/METADATA.DIM

std::string line = image_file;
std::transform(line.begin(), line.end(), line.begin(), ::tolower); // lowercase

std::size_t found = line.rfind("/imagery.b");
if (found == std::string::npos) return "";
std::string prefix = image_file.substr(0, found);

found = line.rfind("front/");
if (found != std::string::npos) {
cam_file = prefix + "/METADATA_FRONT.DIM"; if (fs::exists(cam_file)) return cam_file;
cam_file = prefix + "/metadata_front.dim"; if (fs::exists(cam_file)) return cam_file;
cam_file = prefix + "/METADATA.DIM"; if (fs::exists(cam_file)) return cam_file;
cam_file = prefix + "/metadata.dim"; if (fs::exists(cam_file)) return cam_file;
return "";
}

found = line.rfind("back/");
if (found != std::string::npos) {
cam_file = prefix + "/METADATA_BACK.DIM"; if (fs::exists(cam_file)) return cam_file;
cam_file = prefix + "/metadata_back.dim"; if (fs::exists(cam_file)) return cam_file;
cam_file = prefix + "/METADATA.DIM"; if (fs::exists(cam_file)) return cam_file;
cam_file = prefix + "/metadata.dim"; if (fs::exists(cam_file)) return cam_file;
return "";
}

return "";
}

// Given <tag>12000</tag>, extract the number in between.
// This is robust to whitespace in various places.
bool parse_int_between_tags(std::string const& line, std::string const& tag, int & val){

// Keep the output uninitialized, initialize it only on success
// val = 0;

// advance to the beginning of <tag>
std::size_t found = line.find(tag);
if (found == std::string::npos) return false;

// Advance to the end of <tag>
std::size_t beg = line.find(">", found);
if (beg == std::string::npos) return false;

// Move past "<"
beg++;

// Advance to the beginning of </tag>
std::size_t end = line.find("<", found);
if (end == std::string::npos) return false;

std::string val_str = line.substr(beg, end - beg);

val = atoi(val_str.c_str());

return true;
}

// Find the following text, and read ncols and nrows values
// <Raster_Dimensions>
//<NCOLS>12000</NCOLS>
//<NROWS>46408</NROWS>
//<NBANDS>1</NBANDS>
//</Raster_Dimensions>
vw::ImageFormat image_format_from_DIM(std::string camera_file) {

vw::Vector2i image_size;
std::ifstream ifs(camera_file.c_str());
std::string line;
while (std::getline(ifs, line)){

std::transform(line.begin(), line.end(), line.begin(), ::tolower); // lowercase
std::size_t found = line.find("<raster_dimensions");
if (found == std::string::npos) continue;

std::string cols_tag = "ncols";
std::getline(ifs, line);
std::transform(line.begin(), line.end(), line.begin(), ::tolower); // lowercase
if (!parse_int_between_tags(line, cols_tag, image_size[0]))
continue;

std::string rows_tag = "nrows";
std::getline(ifs, line);
std::transform(line.begin(), line.end(), line.begin(), ::tolower); // lowercase
if (!parse_int_between_tags(line, rows_tag, image_size[1]))
continue;

break;
}

if (image_size[0] <= 0 || image_size[1] <= 0)
vw_throw( ArgumentErr() << "Could not parse correctly the image size from: " << camera_file);

vw::ImageFormat format;
format.cols = image_size[0];
format.rows = image_size[1];
format.planes = 1;
format.pixel_format = vw::VW_PIXEL_GRAY; // This should be constant
format.channel_type = vw::VW_CHANNEL_UINT8;
format.premultiplied = true; // Don't do anything funny to the data
return format;
}

} // end local private namespace

void DiskImageResourceRaw::close() {
m_stream.close();
m_format.cols = 0;
m_format.rows = 0;
}

// Factory functions required by DiskImageResource.cc
DiskImageResource* DiskImageResourceRaw::construct_open( std::string const& filename ) {
std::string dim_file = DIM_lookup(filename);
if (dim_file == "")
vw_throw( ArgumentErr() << "Could not find .DIM file for: " << filename);

return DiskImageResourceRaw::construct(filename, image_format_from_DIM(dim_file));
}

void DiskImageResourceRaw::check_format() const {
if (m_format.planes != 1)
vw_throw( NoImplErr() << "DiskImageResourceRaw does not support multi-plane images.");
Expand Down
6 changes: 2 additions & 4 deletions src/vw/FileIO/DiskImageResourceRaw.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,8 @@ namespace vw {
}

// Factory functions required by DiskImageResource.cc
static DiskImageResource* construct_open( std::string const& filename ) {
vw_throw( NoImplErr() << "Cannot construct DiskImageResourceRaw without header information!");
return 0;
}
static DiskImageResource* construct_open( std::string const& filename );

static DiskImageResource* construct_create( std::string const& filename,
ImageFormat const& format ) {
return new DiskImageResourceRaw(filename, format);
Expand Down
2 changes: 1 addition & 1 deletion src/vw/tools/image2qtree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ load_image_georeferences( const Options& opt, int& total_resolution ) {
georeferences.reserve( opt.input_files.size() );

BOOST_FOREACH(const std::string filename, opt.input_files) {
boost::shared_ptr<DiskImageResource> file( DiskImageResource::open(filename) );
boost::shared_ptr<DiskImageResource> file( DiskImageResourcePtr(filename) );
vw_out() << "Adding file " << file->filename() << std::endl;

if( opt.normalize ) get_normalize_vals(file, opt);
Expand Down
3 changes: 0 additions & 3 deletions src/vw/tools/ipalign.cc
Original file line number Diff line number Diff line change
Expand Up @@ -384,11 +384,8 @@ void handle_arguments( int argc, char* argv[], Options& opt ) {
int main(int argc, char* argv[]) {

Options opt;

handle_arguments( argc, argv, opt ); // Load user arguments
align_images( opt ); // Do all of the work!



return 0;
}

0 comments on commit 06fac3d

Please sign in to comment.