WSL/SLF GitLab Repository

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

The "freeze" color gradient now has a fixed point at zero celsius. A pointer...

The "freeze" color gradient now has a fixed point at zero celsius. A pointer error (related to the FILE pointer) has been fixed in PNGIO by making this pointer a class member. A much improved error message is now generated when a file can not be opened.
parent c0b7d2ff
......@@ -412,7 +412,6 @@ void gr_heat::getColor(const double &i_val, double &r, double &g, double &b) con
}
gr_blue_pink::gr_blue_pink(const double& /*i_min*/, const double& /*i_max*/, const bool& /*i_autoscale*/) {
//write gradient control points
X.push_back(0.); v_h.push_back(0.); v_s.push_back(0.); v_v.push_back(.95); //almost white
X.push_back(0.2); v_h.push_back(172.); v_s.push_back(.4); v_v.push_back(.95); //light blue
X.push_back(.4); v_h.push_back(213.); v_s.push_back(.4); v_v.push_back(.95); //violet
......@@ -421,12 +420,23 @@ gr_blue_pink::gr_blue_pink(const double& /*i_min*/, const double& /*i_max*/, con
X.push_back(1.); v_h.push_back(359.); v_s.push_back(.3); v_v.push_back(.95); //red
}
gr_freeze::gr_freeze(const double& /*i_min*/, const double& /*i_max*/, const bool& /*i_autoscale*/) {
//write gradient control points
X.push_back(0.); v_r.push_back(0.); v_g.push_back(0.); v_b.push_back(1.); //blue
X.push_back(.5); v_r.push_back(1.); v_g.push_back(1.); v_b.push_back(0.); //yellow
X.push_back(.5); v_r.push_back(0.); v_g.push_back(1.); v_b.push_back(0.); //green
X.push_back(1.); v_r.push_back(1.); v_g.push_back(0.); v_b.push_back(0.); //red
gr_freeze::gr_freeze(const double& i_min, const double& i_max, const bool& /*i_autoscale*/) {
//we want the yellow/green step to always be at zero celsius
double begin=0., middle=0.5, end=1.;
if(i_min<0. && i_max>0.) {
const double range = i_max-i_min;
middle = -i_min / range;
} else if(i_min<=0. && i_max<=0.) {
middle = 1.;
end = 1000.;
} else if(i_min>=0. && i_max>=0.) {
begin = -1000.;
middle = 0.;
}
X.push_back(begin); v_r.push_back(0.); v_g.push_back(0.); v_b.push_back(1.); //blue
X.push_back(middle); v_r.push_back(1.); v_g.push_back(1.); v_b.push_back(0.); //yellow
X.push_back(middle); v_r.push_back(0.); v_g.push_back(1.); v_b.push_back(0.); //green
X.push_back(end); v_r.push_back(1.); v_g.push_back(0.); v_b.push_back(0.); //red
}
void gr_freeze::getColor(const double &val, double &r, double &g, double &b) const {
......@@ -437,7 +447,6 @@ void gr_freeze::getColor(const double &val, double &r, double &g, double &b) con
}
gr_blue::gr_blue(const double& /*i_min*/, const double& /*i_max*/, const bool& /*i_autoscale*/) {
//write gradient control points
X.push_back(0.); v_h.push_back(0.); v_s.push_back(0.); v_v.push_back(.99); //5
X.push_back(.16667); v_h.push_back(180.); v_s.push_back(.2); v_v.push_back(.99); //10
X.push_back(.33334); v_h.push_back(193.); v_s.push_back(.32); v_v.push_back(.97); //20
......@@ -449,14 +458,12 @@ gr_blue::gr_blue(const double& /*i_min*/, const double& /*i_max*/, const bool& /
}
gr_bg_isomorphic::gr_bg_isomorphic(const double& /*i_min*/, const double& /*i_max*/, const bool& /*i_autoscale*/) {
//write gradient control points
X.push_back(0.); v_h.push_back(47.); v_s.push_back(.92); v_v.push_back(0.); //black
X.push_back(.5); v_h.push_back(178.); v_s.push_back(.58); v_v.push_back(.67); //light blue
X.push_back(1.); v_h.push_back(84.); v_s.push_back(.67); v_v.push_back(1.); //light green
}
gr_pastel::gr_pastel(const double& /*i_min*/, const double& /*i_max*/, const bool& /*i_autoscale*/) {
//write gradient control points
X.push_back(0.); v_h.push_back(0.); v_s.push_back(1.); v_v.push_back(0.); //black
X.push_back(1./7.); v_h.push_back(185.); v_s.push_back(.26); v_v.push_back(.56); //light blue
X.push_back(2./7.); v_h.push_back(122.); v_s.push_back(.44); v_v.push_back(.91); //light green
......@@ -467,7 +474,6 @@ gr_pastel::gr_pastel(const double& /*i_min*/, const double& /*i_max*/, const boo
}
gr_terrain::gr_terrain(const double& /*i_min*/, const double& i_max, const bool& i_autoscale) {
//write gradient control points
if(i_autoscale) {
X.push_back(0.); v_h.push_back(144.); v_s.push_back(.50); v_v.push_back(.39); //sea level, dark green
X.push_back(.25); v_h.push_back(46.); v_s.push_back(.54); v_v.push_back(.86); //yellow
......@@ -490,19 +496,17 @@ gr_terrain::gr_terrain(const double& /*i_min*/, const double& i_max, const bool&
}
gr_slope::gr_slope(const double& /*i_min*/, const double& /*i_max*/, const bool& /*i_autoscale*/) {
//write gradient control points
//usually, between 0 and 50
X.push_back(0.); v_h.push_back(185.); v_s.push_back(.26); v_v.push_back(.56); //light blue
X.push_back(.5); v_h.push_back(122.); v_s.push_back(.44); v_v.push_back(.91); //light green
X.push_back(.6); v_h.push_back(60.); v_s.push_back(.44); v_v.push_back(.91); //light yellow
X.push_back(.7); v_h.push_back(22.); v_s.push_back(.44); v_v.push_back(.91); //orange
X.push_back(.8); v_h.push_back(0.); v_s.push_back(.44); v_v.push_back(.91); //red
X.push_back(.9); v_h.push_back(0.); v_s.push_back(.58); v_v.push_back(.35); //dark red
X.push_back(1.); v_h.push_back(0.); v_s.push_back(1.); v_v.push_back(0.); //black
X.push_back(.5); v_h.push_back(122.); v_s.push_back(.44); v_v.push_back(.91); //light green, 25
X.push_back(.6); v_h.push_back(60.); v_s.push_back(.44); v_v.push_back(.91); //light yellow, 30
X.push_back(.7); v_h.push_back(22.); v_s.push_back(.44); v_v.push_back(.91); //orange, 35
X.push_back(.8); v_h.push_back(0.); v_s.push_back(.44); v_v.push_back(.91); //red, 40
X.push_back(.9); v_h.push_back(0.); v_s.push_back(.58); v_v.push_back(.35); //dark red, 45
X.push_back(1.); v_h.push_back(0.); v_s.push_back(1.); v_v.push_back(0.); //black, 50
}
gr_azi::gr_azi(const double& /*i_min*/, const double& /*i_max*/, const bool& i_autoscale) {
//write gradient control points
if(i_autoscale) {
X.push_back(0.); v_h.push_back(113.); v_s.push_back(.66); v_v.push_back(.91); //light green
X.push_back(1.); v_h.push_back(360.); v_s.push_back(.66); v_v.push_back(.91); //light red
......
......@@ -20,6 +20,7 @@
#include <meteoio/Graphics.h>
#include <algorithm>
#include <errno.h>
using namespace std;
......@@ -246,15 +247,18 @@ Grid2DObject PNGIO::scaleGrid(const Grid2DObject& grid_in)
}
}
void PNGIO::setFile(const std::string& filename, FILE *fp, png_structp& png_ptr, png_infop& info_ptr, const unsigned int &width, const unsigned int &height)
void PNGIO::setFile(const std::string& filename, png_structp& png_ptr, png_infop& info_ptr, const unsigned int &width, const unsigned int &height)
{
// Open file for writing (binary mode)
if (!IOUtils::validFileName(filename)) {
throw InvalidFileNameException(filename, AT);
}
errno=0;
fp = fopen(filename.c_str(), "wb");
if (fp == NULL) {
throw FileAccessException(filename, AT);
stringstream ss;
ss << "Error openning file \"" << filename << "\", possible reason: " << strerror(errno);
throw FileAccessException(ss.str(), AT);
}
// Initialize write structure
......@@ -275,8 +279,8 @@ void PNGIO::setFile(const std::string& filename, FILE *fp, png_structp& png_ptr,
// Setup Exception handling
if (setjmp(png_jmpbuf(png_ptr))) {
cleanup(fp, png_ptr, info_ptr);
throw IOException("Error during png creation", AT);
closePNG(png_ptr, info_ptr);
throw IOException("Error during png creation. Can not set jump pointer (I have no clue what it means too!)", AT);
}
png_init_io(png_ptr, fp);
......@@ -349,39 +353,20 @@ void PNGIO::writeDataSection(const Grid2DObject &grid, const Array2D<double> &le
png_free(png_ptr, row);
}
void PNGIO::writeWorldFile(const Grid2DObject& grid_in, const std::string& filename)
void PNGIO::closePNG(png_structp& png_ptr, png_infop& info_ptr)
{
const string world_file = IOUtils::removeExtension(filename)+".pnw";
const double cellsize = grid_in.cellsize;
Coords world_ref=grid_in.llcorner;
world_ref.setProj(coordout, coordoutparam);
world_ref.moveByXY(0., grid_in.nrows*cellsize);
std::ofstream fout;
fout.open(world_file.c_str());
if (fout.fail()) {
throw FileAccessException(world_file, AT);
}
try {
fout << std::setprecision(12) << cellsize << "\n";
fout << "0.000000000000\n";
fout << "0.000000000000\n";
fout << std::setprecision(12) << -cellsize << "\n";
fout << std::setprecision(12) << world_ref.getEasting() << "\n";
fout << std::setprecision(12) << world_ref.getNorthing() << "\n";
} catch(...) {
fout.close();
throw FileAccessException("Failed when writing to PNG world file \""+world_file+"\"", AT);
}
fout.close();
fclose(fp);
png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
png_destroy_write_struct(&png_ptr, &info_ptr);
free(info_ptr);
free(png_ptr);
}
void PNGIO::write2DGrid(const Grid2DObject& grid_in, const std::string& filename)
{
string full_name = grid2dpath+"/"+filename;
FILE *fp=NULL;
//FILE *fp=NULL;
fp=NULL;
png_structp png_ptr=NULL;
png_infop info_ptr=NULL;
......@@ -397,7 +382,7 @@ void PNGIO::write2DGrid(const Grid2DObject& grid_in, const std::string& filename
Array2D<double> legend_array; //it will remain empty if there is no legend
const unsigned int full_width = setLegend(ncols, nrows, min, max, legend_array);
setFile(full_name, fp, png_ptr, info_ptr, full_width, nrows);
setFile(full_name, png_ptr, info_ptr, full_width, nrows);
if(has_world_file) writeWorldFile(grid, full_name);
createMetadata(grid);
......@@ -406,9 +391,9 @@ void PNGIO::write2DGrid(const Grid2DObject& grid_in, const std::string& filename
writeMetadata(png_ptr, info_ptr);
writeDataSection(grid, legend_array, gradient, full_width, png_ptr);
png_write_end(png_ptr, NULL);
cleanup(fp, png_ptr, info_ptr);
closePNG(png_ptr, info_ptr);
}
void PNGIO::write2DGrid(const Grid2DObject& grid_in, const MeteoGrids::Parameters& parameter, const Date& date)
......@@ -419,7 +404,8 @@ void PNGIO::write2DGrid(const Grid2DObject& grid_in, const MeteoGrids::Parameter
else
filename = grid2dpath + "/" + date.toString(Date::NUM) + "_" + MeteoGrids::getParameterName(parameter) + ".png";
FILE *fp=NULL;
//FILE *fp=NULL;
fp=NULL;
png_structp png_ptr=NULL;
png_infop info_ptr=NULL;
......@@ -491,7 +477,7 @@ void PNGIO::write2DGrid(const Grid2DObject& grid_in, const MeteoGrids::Parameter
Array2D<double> legend_array; //it will remain empty if there is no legend
const unsigned int full_width = setLegend(ncols, nrows, min, max, legend_array);
setFile(filename, fp, png_ptr, info_ptr, full_width, nrows);
setFile(filename, png_ptr, info_ptr, full_width, nrows);
if(has_world_file) writeWorldFile(grid, filename);
createMetadata(grid);
......@@ -504,10 +490,43 @@ void PNGIO::write2DGrid(const Grid2DObject& grid_in, const MeteoGrids::Parameter
writeMetadata(png_ptr, info_ptr);
writeDataSection(grid, legend_array, gradient, full_width, png_ptr);
png_write_end(png_ptr, NULL);
fflush(fp); //because libpng forgets to flush io buffers.... no comments
cleanup(fp, png_ptr, info_ptr);
closePNG(png_ptr, info_ptr);
/*fclose(fp);
png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
png_destroy_write_struct(&png_ptr, &info_ptr);
free(info_ptr);
free(png_ptr);*/
}
void PNGIO::writeWorldFile(const Grid2DObject& grid_in, const std::string& filename)
{
const string world_file = IOUtils::removeExtension(filename)+".pnw";
const double cellsize = grid_in.cellsize;
Coords world_ref=grid_in.llcorner;
world_ref.setProj(coordout, coordoutparam);
world_ref.moveByXY(0., grid_in.nrows*cellsize);
std::ofstream fout;
fout.open(world_file.c_str());
if (fout.fail()) {
throw FileAccessException(world_file, AT);
}
try {
fout << std::setprecision(12) << cellsize << "\n";
fout << "0.000000000000\n";
fout << "0.000000000000\n";
fout << std::setprecision(12) << -cellsize << "\n";
fout << std::setprecision(12) << world_ref.getEasting() << "\n";
fout << std::setprecision(12) << world_ref.getNorthing() << "\n";
} catch(...) {
fout.close();
throw FileAccessException("Failed when writing to PNG world file \""+world_file+"\"", AT);
}
fout.close();
}
void PNGIO::createMetadata(const Grid2DObject& grid)
......@@ -604,19 +623,6 @@ std::string PNGIO::decimal_to_dms(const double& decimal) {
return dms.str();
}
void PNGIO::cleanup(FILE *fp, png_structp png_ptr, png_infop info_ptr)
{
if (fp != NULL) {
fclose(fp);
fp=NULL;
}
if (info_ptr != NULL) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
if (png_ptr != NULL) png_destroy_write_struct(&png_ptr, &info_ptr);
free(info_ptr); info_ptr = NULL;
free(png_ptr); png_ptr = NULL;
}
#ifndef _METEOIO_JNI
extern "C"
{
......
......@@ -69,14 +69,15 @@ class PNGIO : public IOInterface {
void createMetadata(const Grid2DObject& grid);
void writeMetadata(png_structp &png_ptr, png_infop &info_ptr);
Grid2DObject scaleGrid(const Grid2DObject& grid_in);
void setFile(const std::string& filename, FILE *fp, png_structp& png_ptr, png_infop& info_ptr, const unsigned int &width, const unsigned int &height);
void setFile(const std::string& filename, png_structp& png_ptr, png_infop& info_ptr, const unsigned int &width, const unsigned int &height);
void writeWorldFile(const Grid2DObject& grid_in, const std::string& filename);
unsigned int setLegend(const unsigned int &ncols, const unsigned int &nrows, const double &min, const double &max, Array2D<double> &legend_array);
void writeDataSection(const Grid2DObject &grid, const Array2D<double> &legend_array, const Gradient &gradient, const unsigned int &full_width, const png_structp &png_ptr);
void cleanup(FILE *fp, png_structp png_ptr, png_infop info_ptr);
void closePNG(png_structp& png_ptr, png_infop& info_ptr);
std::string decimal_to_dms(const double& decimal);
Config cfg;
FILE *fp; //since passing fp always fail...
bool autoscale;
bool has_legend;
bool has_world_file; ///< create world file with each file?
......
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