<commit_before>// __BEGIN_LICENSE__
// Copyright (C) 2006, 2007 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__


#ifdef _MSC_VER
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#pragma warning(disable:4996)
#endif

#ifdef NDEBUG
#undef NDEBUG
#endif

#include <stdlib.h>

#include <boost/program_options.hpp>
namespace po = boost::program_options;

#include <vw/Core/Functors.h>
#include <vw/Image/Algorithms.h>
#include <vw/Image/ImageMath.h>
#include <vw/Image/ImageViewRef.h>
#include <vw/Image/PerPixelViews.h>
#include <vw/Image/PixelMask.h>
#include <vw/Image/MaskViews.h>
#include <vw/Image/PixelTypes.h>
#include <vw/Image/Statistics.h>
#include <vw/FileIO/DiskImageView.h>
#include <vw/Cartography/FileIO.h>
#include <vw/Cartography/GeoReference.h>

using namespace vw;

// Global variables
std::string input_file_name, output_file_name = "", shaded_relief_file_name;
float nodata_value;
float min_val = 0, max_val = 0;

// Useful functions

/// Erases a file suffix if one exists and returns the base string
static std::string prefix_from_filename(std::string const& filename) {
  std::string result = filename;
  int index = result.rfind(".");
  if (index != -1) 
    result.erase(index, result.size());
  return result;
}

// Colormap function
class ColormapFunc : public ReturnFixedType<PixelMask<PixelRGB<float> > > {

public:
  ColormapFunc() {}
  
  template <class PixelT>
  PixelMask<PixelRGB<float> > operator() (PixelT const& pix) const {
    if (is_transparent(pix)) 
      return PixelMask<PixelRGB<float> >();
    
    float val = compound_select_channel<const float&>(pix,0);
    if (val > 1.0) val = 1.0;
    if (val < 0.0) val = 0.0;
    
    Vector2 red_range(3/8.0, 1.0);
    Vector2 green_range(2/8.0, 6/8.0);
    Vector2 blue_range(0.0, 5/8.0);

    float red_span = red_range[1] - red_range[0];
    float blue_span = blue_range[1] - blue_range[0];
    float green_span = green_range[1] - green_range[0];

    float red = 0;
    float green = 0;
    float blue = 0;

    // Red
    if (val >= red_range[0] && val <= red_range[0]+red_span/3) 
      red = (val-red_range[0])/(red_span/3);
    if (val >= red_range[0]+red_span/3 && val <= red_range[0]+2*red_span/3) 
      red = 1.0;
    if (val >= red_range[0]+2*red_span/3 && val <= red_range[1]) 
      red = 1-((val-(red_range[0]+2*red_span/3))/(red_span/3));

    // Blue
    if (val >= blue_range[0] && val <= blue_range[0]+blue_span/3) 
      blue = (val-blue_range[0])/(blue_span/3);
    if (val >= blue_range[0]+blue_span/3 && val <= blue_range[0]+2*blue_span/3) 
      blue = 1.0;
    if (val >= blue_range[0]+2*blue_span/3 && val <= blue_range[1]) 
      blue = 1-((val-(blue_range[0]+2*blue_span/3))/(blue_span/3));

     // Green
    if (val >= green_range[0] && val <= green_range[0]+green_span/3) 
      green = (val-green_range[0])/(green_span/3);
    if (val >= green_range[0]+green_span/3 && val <= green_range[0]+2*green_span/3) 
      green = 1.0;
    if (val >= green_range[0]+2*green_span/3 && val <= green_range[1]) 
      green = 1-((val-(green_range[0]+2*green_span/3))/(green_span/3));

    return PixelRGB<float> ( red, green, blue );
  }
};
  
template <class ViewT> 
UnaryPerPixelView<ViewT, ColormapFunc> colormap(ImageViewBase<ViewT> const& view) {
  return UnaryPerPixelView<ViewT, ColormapFunc>(view.impl(), ColormapFunc());
}

// ---------------------------------------------------------------------------------------------------

template <class PixelT>
void do_colorized_dem(po::variables_map const& vm) {

  cartography::GeoReference georef;
  cartography::read_georeference(georef, input_file_name);
  
  DiskImageView<PixelT> disk_dem_file(input_file_name);
  ImageViewRef<PixelGray<float> > input_image = channel_cast<float>(disk_dem_file);

  
  std::cout << "Creating colorized DEM.\n";
  if (min_val == 0 && max_val == 0) {
    min_max_channel_values( create_mask( input_image, nodata_value), min_val, max_val);
    std::cout << "\t--> DEM color map range: [" << min_val << "  " << max_val << "]\n";
  } else {
    std::cout << "\t--> Using user-specified color map range: [" << min_val << "  " << max_val << "]\n";
  }

  ImageViewRef<PixelMask<PixelGray<float> > > dem;
  DiskImageResource *disk_dem_rsrc = DiskImageResource::open(input_file_name);
  if (vm.count("nodata-value")) {
    std::cout << "\t--> Masking nodata value: " << nodata_value << ".\n";
    dem = channel_cast<float>(create_mask(input_image, nodata_value));
  } else if ( disk_dem_rsrc->has_nodata_value() ) {
    nodata_value = disk_dem_rsrc->nodata_value();
    std::cout << "\t--> Extracted nodata value from file: " << nodata_value << ".\n";
    dem = create_mask(input_image, nodata_value);
  } else {
    dem = pixel_cast<PixelMask<PixelGray<float> > >(input_image);
  }
  delete disk_dem_rsrc;

  ImageViewRef<PixelMask<PixelRGB<float> > > colorized_image = colormap(normalize(dem,min_val,max_val,0,1.0));

  if (shaded_relief_file_name != "") {
    std::cout << "\t--> Incorporating hillshading from: " << shaded_relief_file_name << ".\n";
    DiskImageView<PixelMask<float> > shaded_relief_image(shaded_relief_file_name);
    ImageViewRef<PixelMask<PixelRGB<float> > > shaded_image = copy_mask(colorized_image*apply_mask(shaded_relief_image), shaded_relief_image);
    std::cout << "Writing image color-mapped image: " << output_file_name << "\n";
    write_georeferenced_image(output_file_name, channel_cast_rescale<uint8>(shaded_image), georef, TerminalProgressCallback());
  } else {
    std::cout << "Writing image color-mapped image: " << output_file_name << "\n";
    write_georeferenced_image(output_file_name, channel_cast_rescale<uint8>(colorized_image), georef, TerminalProgressCallback());
  }
}


int main( int argc, char *argv[] ) {

  set_debug_level(VerboseDebugMessage-1);
  
  po::options_description desc("Description: Produces a colorized image of a DEM \n\nUsage: colormap [options] <input file> \n\nOptions");
  desc.add_options()
    ("help", "Display this help message")
    ("input-file", po::value<std::string>(&input_file_name), "Explicitly specify the input file")
    ("shaded-relief-file,s", po::value<std::string>(&shaded_relief_file_name)->default_value(""), "Specify a shaded relief image (grayscale) to apply to the colorized image.")
    ("output-file,o", po::value<std::string>(&output_file_name), "Specify the output file")
    ("nodata-value", po::value<float>(&nodata_value), "Remap the DEM default value to the min altitude value.")
    ("min", po::value<float>(&min_val), "Minimum height of the color map.")
    ("max", po::value<float>(&max_val), "Maximum height of the color map.")
    ("moon", "Set the min and max values to [-8499 10208] meters, which is suitable for covering elevations on the Moon.")
    ("mars", "Set the min and max values to [-8208 21249] meters, which is suitable for covering elevations on Mars.")
    ("verbose", "Verbose output");
  po::positional_options_description p;
  p.add("input-file", 1);

  po::variables_map vm;
  po::store( po::command_line_parser( argc, argv ).options(desc).positional(p).run(), vm );
  po::notify( vm );

  if( vm.count("help") ) {
    std::cout << desc << std::endl;
    return 1;
  }

  // This is a reasonable range of elevation values to cover global
  // lunar topography.
  if( vm.count("moon") ) {
    min_val = -8499;  
    max_val = 10208;
  }

  // This is a reasonable range of elevation values to cover global
  // mars topography.
  if( vm.count("mars") ) {
    min_val = -8208;
    max_val = 21249;
  }

  if( vm.count("input-file") != 1 ) {
    std::cout << "Error: Must specify exactly one input file!\n" << std::endl;<commit_msg>Added legend flag for colormap tool.<commit_after>// __BEGIN_LICENSE__
// Copyright (C) 2006, 2007 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__


#ifdef _MSC_VER
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#pragma warning(disable:4996)
#endif

#ifdef NDEBUG
#undef NDEBUG
#endif

#include <stdlib.h>

#include <boost/program_options.hpp>
namespace po = boost::program_options;

#include <vw/Core/Functors.h>
#include <vw/Image/Algorithms.h>
#include <vw/Image/ImageMath.h>
#include <vw/Image/ImageViewRef.h>
#include <vw/Image/PerPixelViews.h>
#include <vw/Image/PixelMask.h>
#include <vw/Image/MaskViews.h>
#include <vw/Image/PixelTypes.h>
#include <vw/Image/Statistics.h>
#include <vw/FileIO/DiskImageView.h>
#include <vw/Cartography/FileIO.h>
#include <vw/Cartography/GeoReference.h>

using namespace vw;

// Global variables
std::string input_file_name, output_file_name = "", shaded_relief_file_name;
float nodata_value;
float min_val = 0, max_val = 0;

// Useful functions

/// Erases a file suffix if one exists and returns the base string
static std::string prefix_from_filename(std::string const& filename) {
  std::string result = filename;
  int index = result.rfind(".");
  if (index != -1) 
    result.erase(index, result.size());
  return result;
}

// Colormap function
class ColormapFunc : public ReturnFixedType<PixelMask<PixelRGB<float> > > {

public:
  ColormapFunc() {}
  
  template <class PixelT>
  PixelMask<PixelRGB<float> > operator() (PixelT const& pix) const {
    if (is_transparent(pix)) 
      return PixelMask<PixelRGB<float> >();
    
    float val = compound_select_channel<const float&>(pix,0);
    if (val > 1.0) val = 1.0;
    if (val < 0.0) val = 0.0;
    
    Vector2 red_range(3/8.0, 1.0);
    Vector2 green_range(2/8.0, 6/8.0);
    Vector2 blue_range(0.0, 5/8.0);

    float red_span = red_range[1] - red_range[0];
    float blue_span = blue_range[1] - blue_range[0];
    float green_span = green_range[1] - green_range[0];

    float red = 0;
    float green = 0;
    float blue = 0;

    // Red
    if (val >= red_range[0] && val <= red_range[0]+red_span/3) 
      red = (val-red_range[0])/(red_span/3);
    if (val >= red_range[0]+red_span/3 && val <= red_range[0]+2*red_span/3) 
      red = 1.0;
    if (val >= red_range[0]+2*red_span/3 && val <= red_range[1]) 
      red = 1-((val-(red_range[0]+2*red_span/3))/(red_span/3));

    // Blue
    if (val >= blue_range[0] && val <= blue_range[0]+blue_span/3) 
      blue = (val-blue_range[0])/(blue_span/3);
    if (val >= blue_range[0]+blue_span/3 && val <= blue_range[0]+2*blue_span/3) 
      blue = 1.0;
    if (val >= blue_range[0]+2*blue_span/3 && val <= blue_range[1]) 
      blue = 1-((val-(blue_range[0]+2*blue_span/3))/(blue_span/3));

     // Green
    if (val >= green_range[0] && val <= green_range[0]+green_span/3) 
      green = (val-green_range[0])/(green_span/3);
    if (val >= green_range[0]+green_span/3 && val <= green_range[0]+2*green_span/3) 
      green = 1.0;
    if (val >= green_range[0]+2*green_span/3 && val <= green_range[1]) 
      green = 1-((val-(green_range[0]+2*green_span/3))/(green_span/3));

    return PixelRGB<float> ( red, green, blue );
  }
};
  
template <class ViewT> 
UnaryPerPixelView<ViewT, ColormapFunc> colormap(ImageViewBase<ViewT> const& view) {
  return UnaryPerPixelView<ViewT, ColormapFunc>(view.impl(), ColormapFunc());
}

// ---------------------------------------------------------------------------------------------------

template <class PixelT>
void do_colorized_dem(po::variables_map const& vm) {

  cartography::GeoReference georef;
  cartography::read_georeference(georef, input_file_name);
  
  DiskImageView<PixelT> disk_dem_file(input_file_name);
  ImageViewRef<PixelGray<float> > input_image = channel_cast<float>(disk_dem_file);

  
  std::cout << "Creating colorized DEM.\n";
  if (min_val == 0 && max_val == 0) {
    min_max_channel_values( create_mask( input_image, nodata_value), min_val, max_val);
    std::cout << "\t--> DEM color map range: [" << min_val << "  " << max_val << "]\n";
  } else {
    std::cout << "\t--> Using user-specified color map range: [" << min_val << "  " << max_val << "]\n";
  }

  ImageViewRef<PixelMask<PixelGray<float> > > dem;
  DiskImageResource *disk_dem_rsrc = DiskImageResource::open(input_file_name);
  if (vm.count("nodata-value")) {
    std::cout << "\t--> Masking nodata value: " << nodata_value << ".\n";
    dem = channel_cast<float>(create_mask(input_image, nodata_value));
  } else if ( disk_dem_rsrc->has_nodata_value() ) {
    nodata_value = disk_dem_rsrc->nodata_value();
    std::cout << "\t--> Extracted nodata value from file: " << nodata_value << ".\n";
    dem = create_mask(input_image, nodata_value);
  } else {
    dem = pixel_cast<PixelMask<PixelGray<float> > >(input_image);
  }
  delete disk_dem_rsrc;

  ImageViewRef<PixelMask<PixelRGB<float> > > colorized_image = colormap(normalize(dem,min_val,max_val,0,1.0));

  if (shaded_relief_file_name != "") {
    std::cout << "\t--> Incorporating hillshading from: " << shaded_relief_file_name << ".\n";
    DiskImageView<PixelMask<float> > shaded_relief_image(shaded_relief_file_name);
    ImageViewRef<PixelMask<PixelRGB<float> > > shaded_image = copy_mask(colorized_image*apply_mask(shaded_relief_image), shaded_relief_image);
    std::cout << "Writing image color-mapped image: " << output_file_name << "\n";
    write_georeferenced_image(output_file_name, channel_cast_rescale<uint8>(shaded_image), georef, TerminalProgressCallback());
  } else {
    std::cout << "Writing image color-mapped image: " << output_file_name << "\n";
    write_georeferenced_image(output_file_name, channel_cast_rescale<uint8>(colorized_image), georef, TerminalProgressCallback());
  }
}

void save_legend() {
  min_val = 0.0;
  max_val = 1.0;
  
  ImageView<PixelGray<float> > img(200, 500);
  for (unsigned j = 0; j < img.rows(); ++j) {
    float val = float(j) / img.rows();
    for (unsigned i = 0; i < img.cols(); ++i) {
      img(i,j) = val;
    }
  }
  
  ImageViewRef<PixelMask<PixelRGB<float> > > colorized_image = colormap(img);
  write_image("legend.png", channel_cast_rescale<uint8>(apply_mask(colorized_image)));
}


int main( int argc, char *argv[] ) {

  set_debug_level(VerboseDebugMessage-1);
  
  po::options_description desc("Description: Produces a colorized image of a DEM \n\nUsage: colormap [options] <input file> \n\nOptions");
  desc.add_options()
    ("help", "Display this help message")
    ("input-file", po::value<std::string>(&input_file_name), "Explicitly specify the input file")
    ("shaded-relief-file,s", po::value<std::string>(&shaded_relief_file_name)->default_value(""), "Specify a shaded relief image (grayscale) to apply to the colorized image.")
    ("output-file,o", po::value<std::string>(&output_file_name), "Specify the output file")
    ("nodata-value", po::value<float>(&nodata_value), "Remap the DEM default value to the min altitude value.")
    ("min", po::value<float>(&min_val), "Minimum height of the color map.")
    ("max", po::value<float>(&max_val), "Maximum height of the color map.")
    ("moon", "Set the min and max values to [-8499 10208] meters, which is suitable for covering elevations on the Moon.")
    ("mars", "Set the min and max values to [-8208 21249] meters, which is suitable for covering elevations on Mars.")
    ("legend", "Generate the colormap legend.  This image is saved (without labels) as \'legend.png\'")
    ("verbose", "Verbose output");
  po::positional_options_description p;
  p.add("input-file", 1);

  po::variables_map vm;
  po::store( po::command_line_parser( argc, argv ).options(desc).positional(p).run(), vm );
  po::notify( vm );

  if( vm.count("help") ) {
    std::cout << desc << std::endl;
    return 1;
  }

  if( vm.count("legend") ) {
    std::cout << "\t--> Saving legend file to disk as \'legend.png\'\n";
    save_legend();
    exit(0);
  }

  // This is a reasonable range of elevation values to cover global
  // lunar topography.
  if( vm.count("moon") ) {
    min_val = -8499;  
    max_val = 10208;
  }

  // This is a reasonable range of elevation values to cover global
  // mars topography.
  if( vm.count("mars") ) {
    min_val = -8208;
    max_val = 21249;
  }

  if( vm.count("input-file") != 1 ) {
    std::cout << "Error: Must specify exactly one input file!\n" << std::endl;
{'fraction_non_alphanumeric': 0.1697021904996308, 'fraction_numerical': 0.02178193453113463, 'mean_word_length': 3.937120291616039, 'pattern_counts': {'":': 0, '<': 267, '<?xml version=': 0, '>': 160, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2610439', 'n_tokens_mistral': 5994, 'n_tokens_neox': 5674, 'n_words': 1252}