WSL/SLF GitLab Repository

Commit c861edcc authored by Mathias Bavay's avatar Mathias Bavay
Browse files

A few more type issues have been fixed. The compilation instructions for...

A few more type issues have been fixed. The compilation instructions for Windows have been detailed for compiling PNGIO (not so easy for Visual c++). PNG_INDEXED and PNG_SPEED_OPTIMIZE are not keys exposed to the end user.
parent 4db92a06
......@@ -27,8 +27,8 @@ namespace mio {
// Legend class
/////////////////////////////////////////////////////////////////////////////////////////////////
const int legend::bg_color = IOUtils::nodata-1;
const int legend::text_color = IOUtils::nodata-2;
const double legend::bg_color = IOUtils::nodata-1;
const double legend::text_color = IOUtils::nodata-2;
const unsigned int legend::char_width = 6;
const unsigned int legend::char_height = 10;
......@@ -120,7 +120,7 @@ void legend::smartLegend(const unsigned int &height, const double &minimum, cons
} else {
step_norm = 0;
decade_mult=1.;
nb_labels_norm=1.;
nb_labels_norm=1;
}
const unsigned int smart_height = nb_labels_norm*legend::label_height+legend::interline;
......@@ -142,12 +142,12 @@ void legend::smartLegend(const unsigned int &height, const double &minimum, cons
}
}
void legend::drawLegend(const unsigned int &height, const double &minimum, const double &maximum) {
void legend::drawLegend(const unsigned int &height, const double &minimum, const double &maximum){
smartLegend(height, minimum, maximum);
//simpleLegend(height, minimum, maximum);
}
double legend::getLegendWidth() {
unsigned int legend::getLegendWidth() {
return total_width;
}
......@@ -201,8 +201,7 @@ void legend::writeChar(const unsigned int i_char[char_height][char_width], const
}
}
const Array2D<double> legend::getLegend()
{
const Array2D<double> legend::getLegend() const {
return grid;
}
......@@ -281,8 +280,8 @@ void Color::HSVtoRGB(const double& h, const double& s, const double& v, double &
// Gradient class
/////////////////////////////////////////////////////////////////////////////////////////////////
const unsigned char Gradient::channel_max_color = 255;
const unsigned int Gradient::reserved_idx = 5;
const unsigned int Gradient::reserved_cols = 2;
const unsigned char Gradient::reserved_idx = 5;
const unsigned char Gradient::reserved_cols = 2;
Gradient::Gradient(const Type& type, const double& i_min, const double& i_max, const bool& i_autoscale)
{
......@@ -308,7 +307,7 @@ void Gradient::set(const Type& type, const double& i_min, const double& i_max, c
else if(type==bg_isomorphic) model = new gr_bg_isomorphic(i_min, i_max, i_autoscale);
}
void Gradient::setNrOfLevels(const unsigned int& i_nr_unique_levels) {
void Gradient::setNrOfLevels(const unsigned char& i_nr_unique_levels) {
if(i_nr_unique_levels<=reserved_idx) {
stringstream ss;
ss << "Insufficient number of colors requested for gradient: ask for more than ";
......@@ -363,7 +362,7 @@ void Gradient::getColor(const double& val, unsigned char& r, unsigned char& g, u
b = static_cast<unsigned char>(b_d*channel_max_color);
}
void Gradient::getColor(const double& val, unsigned int& index) const
void Gradient::getColor(const double& val, unsigned char& index) const
{
if(model==NULL) {
throw UnknownValueException("Please set the color gradient before using it!", AT);
......@@ -393,7 +392,7 @@ void Gradient::getColor(const double& val, unsigned int& index) const
//watch out!! the palette contains some reserved values at the begining
if(val<min) index=reserved_idx-2;
else if(val>max) index=reserved_idx-1;
else index = static_cast<unsigned int>( (val-min)/delta*(double)nr_unique_cols ) + reserved_idx;
else index = static_cast<unsigned char>( (val-min)/delta*(double)nr_unique_cols ) + reserved_idx;
}
void Gradient::getPalette(std::vector<unsigned char> &r, std::vector<unsigned char> &g, std::vector<unsigned char> &b) const
......@@ -429,7 +428,7 @@ void Gradient::getPalette(std::vector<unsigned char> &r, std::vector<unsigned ch
b.push_back( static_cast<unsigned char>(b_d*channel_max_color) );
//all normal colors
for(unsigned int ii=0; ii<=nr_unique_cols; ii++) {
for(unsigned char ii=0; ii<=nr_unique_cols; ii++) {
const double val_norm = (double)ii/(double)nr_unique_cols;
model->getColor(val_norm, r_d, g_d, b_d);
r.push_back( static_cast<unsigned char>(r_d*channel_max_color) );
......
......@@ -50,7 +50,7 @@ class legend {
* This is constant but depends on various parameters of the legend: font size, number of characters, spacing etc.
* @return width of the legend
*/
static double getLegendWidth();
static unsigned int getLegendWidth();
/**
* @brief Get the legend in an array
......@@ -58,10 +58,10 @@ class legend {
* alongside the data array to build the full plot
* @return legend array
*/
const Array2D<double> getLegend();
const Array2D<double> getLegend() const;
static const int bg_color; ///<marker for solid background
static const int text_color; ///<marker for solid text
static const double bg_color; ///<marker for solid background
static const double text_color; ///<marker for solid text
private:
Array2D<double> grid;
......@@ -229,7 +229,7 @@ class Gradient {
* the number of levels/colors remains large enough (say, at least 20-30)
* @param i_nr_unique_levels maximum number of unique levels
*/
void setNrOfLevels(const unsigned int& i_nr_unique_levels);
void setNrOfLevels(const unsigned char& i_nr_unique_levels);
/**
* @brief Get RGB values for a given numeric value
......@@ -248,7 +248,7 @@ class Gradient {
* @param val numerical value to convert
* @param index palette index for the given value
*/
void getColor(const double& val, unsigned int& index) const;
void getColor(const double& val, unsigned char& index) const;
/**
* @brief Get palette colors for the selected gradient
......@@ -264,9 +264,9 @@ class Gradient {
private:
double min, max, delta;
bool autoscale;
unsigned int nr_unique_cols; ///< number of unique colors to generate. The same discretization is performed for indexed or not
static const unsigned int reserved_idx; ///< for indexed gradients, number of reserved indexes
static const unsigned int reserved_cols; ///< for non-indexed gradients, number of reserved colors
unsigned char nr_unique_cols; ///< number of unique colors to generate. The same discretization is performed for indexed or not
static const unsigned char reserved_idx; ///< for indexed gradients, number of reserved indexes
static const unsigned char reserved_cols; ///< for non-indexed gradients, number of reserved colors
Gradient_model *model;
};
......
......@@ -49,6 +49,8 @@ namespace mio {
* - PNG_SCALING: scaling algorithm, either nearest or bilinear (default=bilinear)
* - PNG_AUTOSCALE: autoscale for the color gradient? (default=true)
* - PNG_WORLD_FILE: create world file with each file? (default=false)
* - PNG_INDEXED: create an indexed PNG? (default=true)
* - PNG_SPEED_OPTIMIZE: optimize file creation for speed? (default=true, otherwise optimize for file size)
*
* The size are specified as width followed by height, with the separator being either a space, 'x' or '*'. If a minimum and a maximum size are given, the average of the smallest and largest permissible sizes will be used.
* The world file is used for geolocalization and goes alongside the graphics output. By convention,
......@@ -70,15 +72,27 @@ namespace mio {
* png_min_size = 400x400
* png_max_size = 1366*768
* @endcode
*
* @section Compilation
* In order to compile this plugin, you need libpng and zlib. For Linux, please select both the libraries and their development files in your package manager.
*
* For Windows, you can find zlib at http://switch.dl.sourceforge.net/project/gnuwin32/zlib/1.2.3/zlib-1.2.3.exe
* and libpng at http://switch.dl.sourceforge.net/project/gnuwin32/libpng/1.2.37/libpng-1.2.37-setup.exe . Once this has been installed, if you plan on using
* Visual c++, you also need to edit the file zconf.h in the libpng installation directory and transform the line 287:
* @code
* #if 0 // HAVE_UNISTD_H etc etc
* @endcode
* should become
* @code
* #if 1 // HAVE_UNISTD_H etc etc
* @endcode
*/
const double PNGIO::plugin_nodata = -999.; //plugin specific nodata value. It can also be read by the plugin (depending on what is appropriate)
const unsigned char PNGIO::channel_depth = 8;
const unsigned char PNGIO::channel_max_color = 255;
const unsigned char PNGIO::transparent_grey = channel_max_color;
const bool PNGIO::indexed_png = true;
const bool PNGIO::optimize_for_speed = true;
const unsigned int PNGIO::nr_levels = 30;
const unsigned char PNGIO::nr_levels = 30;
PNGIO::PNGIO(void (*delObj)(void*), const Config& i_cfg) : IOInterface(delObj), cfg(i_cfg)
{
......@@ -123,6 +137,11 @@ void PNGIO::setOptions()
if(min_w!=IOUtils::unodata) min_w -= legend::getLegendWidth();
if(max_w!=IOUtils::unodata) max_w -= legend::getLegendWidth();
}
indexed_png = true;
cfg.getValue("PNG_INDEXED", "Output", indexed_png, Config::nothrow);
optimize_for_speed = true;
cfg.getValue("PNG_SPEED_OPTIMIZE", "Output", optimize_for_speed, Config::nothrow);
}
void PNGIO::parse_size(const std::string& size_spec, unsigned int& width, unsigned int& height)
......@@ -177,7 +196,7 @@ double PNGIO::getScaleFactor(const double& grid_w, const double& grid_h)
}
PNGIO::~PNGIO() throw() {
//HACK: implement a cleanup (close fp, free png pointers, etc
}
void PNGIO::read2DGrid(Grid2DObject&, const std::string&)
......@@ -282,6 +301,9 @@ void PNGIO::setFile(const std::string& filename, png_structp& png_ptr, png_infop
}
// Setup Exception handling
#ifdef _WIN32
#pragma warning(disable:4611) //the setjmp of libpng has been set up so that it can safely be called from c++
#endif
if (setjmp(png_jmpbuf(png_ptr))) {
closePNG(png_ptr, info_ptr, NULL);
throw IOException("Error during png creation. Can not set jump pointer (I have no clue what it means too!)", AT);
......@@ -289,8 +311,9 @@ void PNGIO::setFile(const std::string& filename, png_structp& png_ptr, png_infop
png_init_io(png_ptr, fp);
//png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
if(optimize_for_speed) png_set_compression_level(png_ptr, Z_BEST_SPEED);
else png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_FILTER_SUB|PNG_FILTER_UP); //any other filter is costly and brings close to nothing...
if(indexed_png) png_set_compression_strategy(png_ptr, Z_RLE); //Z_DEFAULT_STRATEGY, Z_FILTERED, Z_HUFFMAN_ONLY, Z_RLE
......@@ -331,15 +354,15 @@ unsigned int PNGIO::setLegend(const unsigned int &ncols, const unsigned int &nro
void PNGIO::writeDataSection(const Grid2DObject &grid, const Array2D<double> &legend_array, const Gradient &gradient, const unsigned int &full_width, const png_structp &png_ptr)
{
const double ncols = grid.ncols;
const double nrows = grid.nrows;
const unsigned int ncols = grid.ncols;
const unsigned int nrows = grid.nrows;
// Allocate memory for one row (3 bytes per pixel - RGB)
unsigned char channels;
if(indexed_png)
channels = 1;
else
channels = 3;
channels = 3; //4 for rgba
png_bytep row = (png_bytep)calloc(channels*sizeof(png_byte), full_width);
if(row==NULL) {
......@@ -348,24 +371,24 @@ void PNGIO::writeDataSection(const Grid2DObject &grid, const Array2D<double> &le
// Write image data
if(indexed_png) {
for(int y=nrows-1 ; y>=0 ; y--) {
for(int y=(signed)nrows-1 ; y>=0 ; y--) {
unsigned int x=0;
for(; x<ncols ; x++) {
const unsigned int i=x*channels;
unsigned int index;
unsigned char index;
gradient.getColor(grid(x,y), index);
row[i]=index;
row[i]=static_cast<png_byte>(index);
}
for(; x<full_width; x++) {
const unsigned int i=x*channels;
unsigned int index;
unsigned char index;
gradient.getColor(legend_array(x-ncols,y), index);
row[i]=index;
row[i]=static_cast<png_byte>(index);
}
png_write_row(png_ptr, row);
}
} else {
for(int y=nrows-1 ; y>=0 ; y--) {
for(int y=(signed)nrows-1 ; y>=0 ; y--) {
unsigned int x=0;
for(; x<ncols ; x++) {
const unsigned int i=x*channels;
......@@ -373,9 +396,9 @@ void PNGIO::writeDataSection(const Grid2DObject &grid, const Array2D<double> &le
bool a;
gradient.getColor(grid(x,y), r,g,b,a);
if(a==true) {
row[i]=transparent_grey; row[i+1]=transparent_grey; row[i+2]=transparent_grey;
row[i]=static_cast<png_byte>(transparent_grey); row[i+1]=static_cast<png_byte>(transparent_grey); row[i+2]=static_cast<png_byte>(transparent_grey);
} else {
row[i]=r; row[i+1]=g; row[i+2]=b;
row[i]=static_cast<png_byte>(r); row[i+1]=static_cast<png_byte>(g); row[i+2]=static_cast<png_byte>(b);
}
}
for(; x<full_width; x++) {
......@@ -384,9 +407,9 @@ void PNGIO::writeDataSection(const Grid2DObject &grid, const Array2D<double> &le
bool a;
gradient.getColor(legend_array(x-ncols,y), r,g,b,a);
if(a==true) {
row[i]=transparent_grey; row[i+1]=transparent_grey; row[i+2]=transparent_grey;
row[i]=static_cast<png_byte>(transparent_grey); row[i+1]=static_cast<png_byte>(transparent_grey); row[i+2]=static_cast<png_byte>(transparent_grey);
} else {
row[i]=r; row[i+1]=g; row[i+2]=b;
row[i]=static_cast<png_byte>(r); row[i+1]=static_cast<png_byte>(g); row[i+2]=static_cast<png_byte>(b);
}
}
png_write_row(png_ptr, row);
......@@ -402,11 +425,11 @@ void PNGIO::setPalette(const Gradient &gradient, png_structp& png_ptr, png_infop
std::vector<unsigned char> r, g, b;
gradient.getPalette(r,g,b);
const size_t nr_colors = r.size();
palette = (png_color*)calloc(sizeof (png_color), nr_colors);
palette = (png_color*)calloc(sizeof (png_color), nr_colors); //ie: three png_bytes, each being an unsigned char
for(size_t ii=0; ii<nr_colors; ii++) {
palette[ii].red = r[ii];
palette[ii].green = g[ii];
palette[ii].blue = b[ii];
palette[ii].red = static_cast<png_byte>(r[ii]);
palette[ii].green = static_cast<png_byte>(g[ii]);
palette[ii].blue = static_cast<png_byte>(b[ii]);
}
png_set_PLTE(png_ptr, info_ptr, palette, nr_colors);
}
......@@ -431,7 +454,7 @@ void PNGIO::write2DGrid(const Grid2DObject& grid_in, const std::string& filename
//scale input image
const Grid2DObject grid = scaleGrid(grid_in);
const double ncols = grid.ncols, nrows = grid.nrows;
const unsigned int ncols = grid.ncols, nrows = grid.nrows;
const double min = grid.grid2D.getMin();
const double max = grid.grid2D.getMax();
......@@ -474,7 +497,7 @@ void PNGIO::write2DGrid(const Grid2DObject& grid_in, const MeteoGrids::Parameter
//scale input image
Grid2DObject grid = scaleGrid(grid_in);
const double ncols = grid.ncols, nrows = grid.nrows;
const unsigned int ncols = grid.ncols, nrows = grid.nrows;
double min = grid.grid2D.getMin();
double max = grid.grid2D.getMax();
......
......@@ -82,6 +82,8 @@ class PNGIO : public IOInterface {
bool autoscale;
bool has_legend;
bool has_world_file; ///< create world file with each file?
bool optimize_for_speed; ///< optimize for speed instead of compression?
bool indexed_png; ///< write an indexed png?
std::string coordout, coordoutparam; //projection parameters
std::string grid2dpath;
......@@ -94,9 +96,7 @@ class PNGIO : public IOInterface {
static const unsigned char channel_depth;
static const unsigned char channel_max_color;
static const unsigned char transparent_grey;
static const bool optimize_for_speed; ///< optimize for speed instead of compression?
static const bool indexed_png; ///< write an indexed png?
static const unsigned int nr_levels; ///< number of levels to represent? (less-> smaller file size and faster)
static const unsigned char nr_levels; ///< number of levels to represent? (less-> smaller file size and faster)
};
} //namespace
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment