Michael Uleysky
9 years ago
2 changed files with 517 additions and 0 deletions
@ -0,0 +1,135 @@ |
|||||||
|
// From grayscale
|
||||||
|
struct gmt_color Gray2RGB() const |
||||||
|
{ |
||||||
|
struct gmt_color color; |
||||||
|
color.transparency=transparency; |
||||||
|
color.model=RGB; |
||||||
|
color.r=color.g=color.b=gray; |
||||||
|
return color; |
||||||
|
} |
||||||
|
struct gmt_color Gray2HSV() const |
||||||
|
{ |
||||||
|
struct gmt_color color; |
||||||
|
color.transparency=transparency; |
||||||
|
color.model=HSV; |
||||||
|
color.hue=0; |
||||||
|
color.saturation=0; |
||||||
|
color.value=gray/255.0; |
||||||
|
return color; |
||||||
|
} |
||||||
|
struct gmt_color Gray2CMYK() const |
||||||
|
{ |
||||||
|
struct gmt_color color; |
||||||
|
color.transparency=transparency; |
||||||
|
color.model=CMYK; |
||||||
|
color.cyan=color.magenta=color.yellow=0; |
||||||
|
color.black=(1.0-gray/255.0)*100.0; |
||||||
|
return color; |
||||||
|
} |
||||||
|
|
||||||
|
// From RGB
|
||||||
|
struct gmt_color RGB2Gray() const |
||||||
|
{ |
||||||
|
struct gmt_color color; |
||||||
|
color.transparency=transparency; |
||||||
|
color.model=GRAY; |
||||||
|
color.gray=0.2126*r+0.7152*g+0.0722*b; |
||||||
|
return color; |
||||||
|
} |
||||||
|
struct gmt_color RGB2HSV() const |
||||||
|
{ |
||||||
|
struct gmt_color color; |
||||||
|
color.transparency=transparency; |
||||||
|
color.model=HSV; |
||||||
|
double rr=r/255.0,gg=g/255.0,bb=b/255.0; |
||||||
|
double cmax=std::max(rr,std::max(gg,bb)); |
||||||
|
double cmin=std::min(rr,std::min(gg,bb)); |
||||||
|
double delta=cmax-cmin; |
||||||
|
|
||||||
|
if(0==delta) color.hue=0; |
||||||
|
else if(cmax==rr) |
||||||
|
{ |
||||||
|
double x=(gg-bb)/delta; |
||||||
|
color.hue=x-floor(x/6.0)*6.0; |
||||||
|
} |
||||||
|
else if(cmax==gg) color.hue=(bb-rr)/delta+2.0; |
||||||
|
else if(cmax==bb) color.hue=(rr-gg)/delta+4.0; |
||||||
|
color.hue*=60.0; |
||||||
|
color.saturation=(0==cmax)?0:(delta/cmax); |
||||||
|
color.value=cmax; |
||||||
|
|
||||||
|
return color; |
||||||
|
} |
||||||
|
struct gmt_color RGB2CMYK() const |
||||||
|
{ |
||||||
|
struct gmt_color color; |
||||||
|
color.transparency=transparency; |
||||||
|
color.model=CMYK; |
||||||
|
double rr=r/255.0,gg=g/255.0,bb=b/255.0; |
||||||
|
double k=1.0-std::max(rr,std::max(gg,bb)); |
||||||
|
|
||||||
|
color.black=k; |
||||||
|
color.cyan=(1.0-rr-k)/(1.0-k); |
||||||
|
color.magenta=(1.0-gg-k)/(1.0-k); |
||||||
|
color.yellow=(1.0-bb-k)/(1.0-k); |
||||||
|
if(0.0==1.0-k) color.cyan=color.magenta=color.yellow=0.0; |
||||||
|
color.black*=100.0; |
||||||
|
color.cyan*=100.0; |
||||||
|
color.magenta*=100.0; |
||||||
|
color.yellow*=100.0; |
||||||
|
|
||||||
|
return color; |
||||||
|
} |
||||||
|
|
||||||
|
// From HSV
|
||||||
|
struct gmt_color HSV2Gray() const |
||||||
|
{ |
||||||
|
return HSV2RGB().RGB2Gray(); |
||||||
|
} |
||||||
|
struct gmt_color HSV2RGB() const |
||||||
|
{ |
||||||
|
struct gmt_color color; |
||||||
|
color.transparency=transparency; |
||||||
|
color.model=RGB; |
||||||
|
double c=saturation*value; |
||||||
|
double x=c*(1.0-fabs((hue/60.0)-floor((hue/60.0)/2.0)*2.0-1.0)); |
||||||
|
double m=value-c; |
||||||
|
|
||||||
|
if(0.0 <=hue && 60.0 >hue) {color.r=c; color.g=x; color.b=0;} |
||||||
|
if(60.0 <=hue && 120.0>hue) {color.r=x; color.g=c; color.b=0;} |
||||||
|
if(120.0<=hue && 180.0>hue) {color.r=0; color.g=c; color.b=x;} |
||||||
|
if(180.0<=hue && 240.0>hue) {color.r=0; color.g=x; color.b=c;} |
||||||
|
if(240.0<=hue && 300.0>hue) {color.r=x; color.g=0; color.b=c;} |
||||||
|
if(300.0<=hue &&360.0>=hue) {color.r=c; color.g=0; color.b=x;} |
||||||
|
color.r+=m; color.g+=m; color.b+=m; |
||||||
|
color.r*=255; color.g*=255; color.b*=255; |
||||||
|
|
||||||
|
return color; |
||||||
|
} |
||||||
|
struct gmt_color HSV2CMYK() const |
||||||
|
{ |
||||||
|
return HSV2RGB().RGB2CMYK(); |
||||||
|
} |
||||||
|
|
||||||
|
// From CMYK
|
||||||
|
struct gmt_color CMYK2Gray() const |
||||||
|
{ |
||||||
|
return CMYK2RGB().RGB2Gray(); |
||||||
|
} |
||||||
|
struct gmt_color CMYK2RGB() const |
||||||
|
{ |
||||||
|
struct gmt_color color; |
||||||
|
color.transparency=transparency; |
||||||
|
color.model=RGB; |
||||||
|
double cc=cyan/100.0,mm=magenta/100.0,yy=yellow/100.0,kk=black/100.0; |
||||||
|
|
||||||
|
color.r=255.0*(1.0-cc)*(1.0-kk); |
||||||
|
color.g=255.0*(1.0-mm)*(1.0-kk); |
||||||
|
color.b=255.0*(1.0-yy)*(1.0-kk); |
||||||
|
|
||||||
|
return color; |
||||||
|
} |
||||||
|
struct gmt_color CMYK2HSV() const |
||||||
|
{ |
||||||
|
return CMYK2RGB().RGB2HSV(); |
||||||
|
} |
@ -0,0 +1,382 @@ |
|||||||
|
#ifndef MODGMT_STRUCT_H |
||||||
|
#define MODGMT_STRUCT_H |
||||||
|
#include <cinttypes> |
||||||
|
|
||||||
|
// Coordinate
|
||||||
|
struct gmt_coord |
||||||
|
{ |
||||||
|
bool isdeg; |
||||||
|
union |
||||||
|
{ |
||||||
|
double r; |
||||||
|
struct |
||||||
|
{ |
||||||
|
bool sign; |
||||||
|
uint16_t d; |
||||||
|
uint8_t m; |
||||||
|
double s; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
std::string Value() const |
||||||
|
{ |
||||||
|
if(!isdeg) return std::to_string(r); |
||||||
|
else return (sign?"":"-")+std::to_string(d)+":"+std::to_string(m)+(s==0?"":":"+std::to_string(s)); |
||||||
|
} |
||||||
|
operator double() const |
||||||
|
{ |
||||||
|
if(isdeg) return (d+(m+s/60.0)/60.0)*(sign?1:-1); |
||||||
|
else return r; |
||||||
|
} |
||||||
|
bool Convert(const std::string& str) |
||||||
|
{ |
||||||
|
size_t bpos=0,pos=str.find(':'); |
||||||
|
if(std::string::npos==pos) |
||||||
|
{ |
||||||
|
isdeg=false; |
||||||
|
return str2double(str,&r); |
||||||
|
} |
||||||
|
|
||||||
|
isdeg=true; |
||||||
|
int64_t res; |
||||||
|
|
||||||
|
// degrees
|
||||||
|
if(! str2int(std::string(str.c_str(),str.c_str()+pos),&res) ) return false; |
||||||
|
if(res>360 || res<-360) res%=360; |
||||||
|
sign=(std::string::npos==str.find('-')); |
||||||
|
d=static_cast<uint16_t>(sign?res:-res); |
||||||
|
// minutes
|
||||||
|
bpos=pos+1; |
||||||
|
pos=str.find(':',bpos); |
||||||
|
if(std::string::npos==pos) |
||||||
|
{ |
||||||
|
if(!str2int(str.substr(bpos),&res)) return false; |
||||||
|
if(res<0 || res>=60) return false; |
||||||
|
m=static_cast<uint8_t>(res); |
||||||
|
s=0; |
||||||
|
return true; |
||||||
|
} |
||||||
|
if(! str2int(std::string(str.c_str()+bpos,str.c_str()+pos),&res) ) return false; |
||||||
|
if(res<0 || res>=60) return false; |
||||||
|
m=static_cast<uint8_t>(res); |
||||||
|
// seconds
|
||||||
|
if(! str2double(str.substr(pos+1),&s) ) return false; |
||||||
|
if(s<0.0 || s>=60.0) return false; |
||||||
|
return true; |
||||||
|
} |
||||||
|
bool Convert(double num) |
||||||
|
{ |
||||||
|
isdeg=false; |
||||||
|
r=num; |
||||||
|
return true; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
// Region
|
||||||
|
struct gmt_region |
||||||
|
{ |
||||||
|
enum Type {NORMAL,BBOX,GLOBAL360,GLOBAL180}; |
||||||
|
Type type; |
||||||
|
struct gmt_coord xb,xe,yb,ye; |
||||||
|
|
||||||
|
std::string Value() const |
||||||
|
{ |
||||||
|
switch(type) |
||||||
|
{ |
||||||
|
case(NORMAL): return std::string("-R")+xb.Value()+"/"+xe.Value()+"/"+yb.Value()+"/"+ye.Value(); |
||||||
|
case(BBOX): return std::string("-R")+xb.Value()+"/"+yb.Value()+"/"+xe.Value()+"/"+ye.Value()+"r"; |
||||||
|
case(GLOBAL360): return "-Rg"; |
||||||
|
case(GLOBAL180): return "-Rd"; |
||||||
|
} |
||||||
|
return ""; |
||||||
|
} |
||||||
|
|
||||||
|
// Only "global", "global180" and "global360"
|
||||||
|
// TODO: add parsing of "-R" strings
|
||||||
|
bool Convert(const std::string& istr) |
||||||
|
{ |
||||||
|
std::string str=istr; |
||||||
|
tolower(str); |
||||||
|
if("global180"==str) |
||||||
|
{ |
||||||
|
type=GLOBAL180; |
||||||
|
xb.Convert(-180.0); xe.Convert(180.0); |
||||||
|
yb.Convert(-90.0); ye.Convert(90.0); |
||||||
|
return true; |
||||||
|
} |
||||||
|
if("global360"==str || "global"==str) |
||||||
|
{ |
||||||
|
type=GLOBAL360; |
||||||
|
xb.Convert(0.0); xe.Convert(360.0); |
||||||
|
yb.Convert(-90.0); ye.Convert(90.0); |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
// Make by coordinates
|
||||||
|
bool Convert(struct gmt_coord ixb, struct gmt_coord ixe, struct gmt_coord iyb, struct gmt_coord iye, bool isbbox=false) |
||||||
|
{ |
||||||
|
type=isbbox?BBOX:NORMAL; |
||||||
|
xb=ixb; yb=iyb; xe=ixe; ye=iye; |
||||||
|
return true; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
// Projection
|
||||||
|
struct gmt_projection |
||||||
|
{ |
||||||
|
// OBLIQMERCATOR types
|
||||||
|
enum class OType {A,B,C}; |
||||||
|
// No UTM (-Ju)
|
||||||
|
enum projection {XY,CYL_EQU,MERCATOR,TRANSMERCATOR,OBLIQMERCATOR,CASSINI,CYL_EQA,MILLER,CYL_STERE}; |
||||||
|
// Real size in cm of drawing area
|
||||||
|
double rwidth,rheight; |
||||||
|
|
||||||
|
struct gmt_region region; |
||||||
|
projection proj; |
||||||
|
double width; // parameter of projection
|
||||||
|
|
||||||
|
union // other projection parameters
|
||||||
|
{ |
||||||
|
// XY
|
||||||
|
struct {double height;} x; |
||||||
|
// Cylindrical projections
|
||||||
|
// CYL_EQU (Cylindrical Equidistant -Jq)
|
||||||
|
struct {double stpar,cmer;} q; |
||||||
|
// MERCATOR (-Jm)
|
||||||
|
struct {double stpar,cmer;} m; |
||||||
|
// TRANSMERCATOR (-Jt)
|
||||||
|
struct {double cmer,orlat,scale;} t; |
||||||
|
// OBLIQMERCATOR (-Jo)
|
||||||
|
struct |
||||||
|
{ |
||||||
|
OType type; |
||||||
|
double clon,clat; |
||||||
|
union |
||||||
|
{ |
||||||
|
double azimuth; // A
|
||||||
|
struct {double eqlon,eqlat;}; // B
|
||||||
|
struct {double polelon,polelat;}; // C
|
||||||
|
}; |
||||||
|
} o; |
||||||
|
// CASSINI (-Jc)
|
||||||
|
struct {double clon,clat;} c; |
||||||
|
// CYL_EQA (Cylindrical equal-area -Jy)
|
||||||
|
struct {double stpar,cmer;} y; |
||||||
|
// MILLER (-Jj)
|
||||||
|
struct {double cmer;} j; |
||||||
|
// CYL_STERE (Cylindrical stereographic -Jcyl_stere)
|
||||||
|
struct {double stpar,cmer;} cyl_stere; |
||||||
|
}; |
||||||
|
std::string Value() const |
||||||
|
{ |
||||||
|
switch(proj) |
||||||
|
{ |
||||||
|
case(XY): return "-JX"+std::to_string(width)+"c/"+std::to_string(x.height)+"c"; |
||||||
|
case(CYL_EQU): return "-JQ"+std::to_string(q.cmer)+"/"+std::to_string(q.stpar)+"/"+std::to_string(width)+"c"; |
||||||
|
case(MERCATOR): return "-JM"+std::to_string(m.cmer)+"/"+std::to_string(m.stpar)+"/"+std::to_string(width)+"c"; |
||||||
|
case(TRANSMERCATOR): return "-JT"+std::to_string(t.cmer)+"/"+std::to_string(t.orlat)+"/"+std::to_string(width)+"c --PROJ_SCALE_FACTOR="+std::to_string(t.scale); |
||||||
|
case(OBLIQMERCATOR): |
||||||
|
{ |
||||||
|
switch(o.type) |
||||||
|
{ |
||||||
|
case(OType::A): return "-JOa"+std::to_string(o.clon)+"/"+std::to_string(o.clat)+"/"+std::to_string(o.azimuth)+"/"+std::to_string(width)+"c"; |
||||||
|
case(OType::B): return "-JOb"+std::to_string(o.clon)+"/"+std::to_string(o.clat)+"/"+std::to_string(o.eqlon)+"/"+std::to_string(o.eqlat)+"/"+std::to_string(width)+"c"; |
||||||
|
case(OType::C): return "-JOb"+std::to_string(o.clon)+"/"+std::to_string(o.clat)+"/"+std::to_string(o.polelon)+"/"+std::to_string(o.polelat)+"/"+std::to_string(width)+"c"; |
||||||
|
} |
||||||
|
} |
||||||
|
case(CASSINI): return "-JC"+std::to_string(c.clon)+"/"+std::to_string(c.clat)+"/"+std::to_string(width)+"c"; |
||||||
|
case(CYL_EQA): return "-JY"+std::to_string(y.stpar)+"/"+std::to_string(y.cmer)+"/"+std::to_string(width)+"c"; |
||||||
|
case(MILLER): return "-JJ"+std::to_string(j.cmer)+"/"+std::to_string(width)+"c"; |
||||||
|
case(CYL_STERE): return "-JCyl_stere"+std::to_string(cyl_stere.stpar)+"/"+std::to_string(cyl_stere.cmer)+"/"+std::to_string(width)+"c"; |
||||||
|
} |
||||||
|
return ""; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
// Color
|
||||||
|
struct gmt_color |
||||||
|
{ |
||||||
|
enum ColorModel {RGB,GRAY,HSV,CMYK}; |
||||||
|
ColorModel model; |
||||||
|
union |
||||||
|
{ |
||||||
|
double gray; // 0-255
|
||||||
|
struct {double r,g,b;}; // 0-255
|
||||||
|
struct {double hue,saturation,value;}; // 0-360, 0-1, 0-1
|
||||||
|
struct {double cyan,magenta,yellow,black;}; // 0-100
|
||||||
|
}; |
||||||
|
double transparency; |
||||||
|
std::string Value() const |
||||||
|
{ |
||||||
|
std::string trans=(transparency!=0)?("@"+std::to_string(transparency)):""; |
||||||
|
switch(model) |
||||||
|
{ |
||||||
|
case(RGB): return std::to_string(r)+"/"+std::to_string(g)+"/"+std::to_string(b)+trans; |
||||||
|
case(GRAY): return std::to_string(gray)+trans; |
||||||
|
case(HSV): return std::to_string(hue)+"-"+std::to_string(saturation)+"-"+std::to_string(value)+trans; |
||||||
|
case(CMYK): return std::to_string(cyan)+"/"+std::to_string(magenta)+"/"+std::to_string(yellow)+"/"+std::to_string(black)+trans; |
||||||
|
} |
||||||
|
return ""; |
||||||
|
} |
||||||
|
double Gray() const |
||||||
|
{ |
||||||
|
switch(model) |
||||||
|
{ |
||||||
|
case(RGB): return RGB2Gray().gray; |
||||||
|
case(GRAY): return gray; |
||||||
|
case(HSV): return HSV2Gray().gray; |
||||||
|
case(CMYK): return CMYK2Gray().gray; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
double R() const |
||||||
|
{ |
||||||
|
switch(model) |
||||||
|
{ |
||||||
|
case(RGB): return r; |
||||||
|
case(GRAY): return Gray2RGB().r; |
||||||
|
case(HSV): return HSV2RGB().r; |
||||||
|
case(CMYK): return CMYK2RGB().r; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
double G() const |
||||||
|
{ |
||||||
|
switch(model) |
||||||
|
{ |
||||||
|
case(RGB): return g; |
||||||
|
case(GRAY): return Gray2RGB().g; |
||||||
|
case(HSV): return HSV2RGB().g; |
||||||
|
case(CMYK): return CMYK2RGB().g; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
double B() const |
||||||
|
{ |
||||||
|
switch(model) |
||||||
|
{ |
||||||
|
case(RGB): return b; |
||||||
|
case(GRAY): return Gray2RGB().b; |
||||||
|
case(HSV): return HSV2RGB().b; |
||||||
|
case(CMYK): return CMYK2RGB().b; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
double H() const |
||||||
|
{ |
||||||
|
switch(model) |
||||||
|
{ |
||||||
|
case(RGB): return RGB2HSV().hue; |
||||||
|
case(GRAY): return Gray2HSV().hue; |
||||||
|
case(HSV): return hue; |
||||||
|
case(CMYK): return CMYK2HSV().hue; |
||||||
|
} |
||||||
|
return 0;// Own functions
|
||||||
|
} |
||||||
|
double S() const |
||||||
|
{ |
||||||
|
switch(model) |
||||||
|
{ |
||||||
|
case(RGB): return RGB2HSV().saturation; |
||||||
|
case(GRAY): return Gray2HSV().saturation; |
||||||
|
case(HSV): return saturation; |
||||||
|
case(CMYK): return CMYK2HSV().saturation; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
double V() const |
||||||
|
{ |
||||||
|
switch(model) |
||||||
|
{ |
||||||
|
case(RGB): return RGB2HSV().value; |
||||||
|
case(GRAY): return Gray2HSV().value; |
||||||
|
case(HSV): return value; |
||||||
|
case(CMYK): return CMYK2HSV().value; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
double C() const |
||||||
|
{ |
||||||
|
switch(model) |
||||||
|
{ |
||||||
|
case(RGB): return RGB2CMYK().cyan; |
||||||
|
case(GRAY): return Gray2CMYK().cyan; |
||||||
|
case(HSV): return HSV2CMYK().cyan; |
||||||
|
case(CMYK): return cyan; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
double M() const |
||||||
|
{ |
||||||
|
switch(model) |
||||||
|
{ |
||||||
|
case(RGB): return RGB2CMYK().magenta; |
||||||
|
case(GRAY): return Gray2CMYK().magenta; |
||||||
|
case(HSV): return HSV2CMYK().magenta; |
||||||
|
case(CMYK): return magenta; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
double Y() const |
||||||
|
{ |
||||||
|
switch(model) |
||||||
|
{ |
||||||
|
case(RGB): return RGB2CMYK().yellow; |
||||||
|
case(GRAY): return Gray2CMYK().yellow; |
||||||
|
case(HSV): return HSV2CMYK().yellow; |
||||||
|
case(CMYK): return yellow; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
double K() const |
||||||
|
{ |
||||||
|
switch(model) |
||||||
|
{ |
||||||
|
case(RGB): return RGB2CMYK().black; |
||||||
|
case(GRAY): return Gray2CMYK().black; |
||||||
|
case(HSV): return HSV2CMYK().black; |
||||||
|
case(CMYK): return black; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
// Transformation functions
|
||||||
|
private: |
||||||
|
#include "colortransform.h" |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
// Dash
|
||||||
|
struct gmt_dash |
||||||
|
{ |
||||||
|
std::vector<double> dash; |
||||||
|
double shift; |
||||||
|
std::string Value() const |
||||||
|
{ |
||||||
|
std::string ret; |
||||||
|
if(dash.empty()) return ret; |
||||||
|
for(auto i:dash) ret+=std::to_string(i)+"_"; |
||||||
|
ret.back()=':'; |
||||||
|
ret+=std::to_string(shift)+"c"; |
||||||
|
return ret; |
||||||
|
} |
||||||
|
operator bool() const {return !dash.empty();} |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
// Pen
|
||||||
|
struct gmt_pen |
||||||
|
{ |
||||||
|
double width; |
||||||
|
struct gmt_color color; |
||||||
|
struct gmt_dash dash; |
||||||
|
std::string Value() const {return std::to_string(width)+","+color.Value()+(dash?(","+dash.Value()):"");} |
||||||
|
}; |
||||||
|
#endif |
Loading…
Reference in new issue