summaryrefslogtreecommitdiff
path: root/rotord/rotor.h
diff options
context:
space:
mode:
Diffstat (limited to 'rotord/rotor.h')
-rwxr-xr-xrotord/rotor.h185
1 files changed, 183 insertions, 2 deletions
diff --git a/rotord/rotor.h b/rotord/rotor.h
index fe0f7d9..137f8ee 100755
--- a/rotord/rotor.h
+++ b/rotord/rotor.h
@@ -141,6 +141,23 @@ namespace Rotor {
return (int)((time*framerate)+0.5); //rounded to the nearest frame
}
};
+ class Colour{
+ public:
+ Colour(){
+ r=g=b=0;
+ }
+ Colour(int c){
+ r=c&0xFF;
+ g=(c&0xFF00)>>8;
+ b=(c&0xFF0000)>>16;
+ }
+ Colour(std::string s){
+ r=(uint8_t)ofHexToChar(s.substr(0,2));
+ g=(uint8_t)ofHexToChar(s.substr(2,2));
+ b=(uint8_t)ofHexToChar(s.substr(4,2));
+ }
+ uint8_t r,g,b;
+ };
class Image{
public:
Image(){
@@ -237,6 +254,42 @@ namespace Rotor {
}
return other;
}
+ Image * operator+(const float &amount) {
+ Image *other=new Image();
+ other->setup(w,h);
+ uint8_t *LUT=new uint8_t[0xFF];
+ for (int i=0;i<0xFF;i++) {
+ LUT[i]=(uint8_t)min(0xFF,max(0,(int)(i+amount))); //should normalise to 0-255?
+ }
+ for (int i=0;i<w*h*3;i++){
+ other->RGBdata[i]=LUT[RGBdata[i]];
+ }
+ return other;
+ }
+ Image * operator-(const float &amount) {
+ Image *other=new Image();
+ other->setup(w,h);
+ uint8_t *LUT=new uint8_t[0xFF];
+ for (int i=0;i<0xFF;i++) {
+ LUT[i]=(uint8_t)min(0xFF,max(0,(int)(i-amount))); //should normalise to 0-255?
+ }
+ for (int i=0;i<w*h*3;i++){
+ other->RGBdata[i]=LUT[RGBdata[i]];
+ }
+ return other;
+ }
+ Image * operator/(const float &amount) {
+ Image *other=new Image();
+ other->setup(w,h);
+ uint8_t *LUT=new uint8_t[0xFF];
+ for (int i=0;i<0xFF;i++) {
+ LUT[i]=(uint8_t)min(0xFF,max(0,(int)(i/amount))); //should normalise to 0-255?
+ }
+ for (int i=0;i<w*h*3;i++){
+ other->RGBdata[i]=LUT[RGBdata[i]];
+ }
+ return other;
+ }
uint8_t *RGBdata;
uint8_t *Adata;
uint16_t *Zdata;
@@ -678,6 +731,130 @@ namespace Rotor {
Video_cycler* clone(map<string,string> &_settings) { return new Video_cycler(_settings);};
private:
};
+ class Signal_colour: public Image_node {
+ //cycles through video inputs in order
+ public:
+ Signal_colour(){};
+ Signal_colour(map<string,string> &settings) {
+ base_settings(settings);
+ string colours=find_setting(settings,"palette","");
+ for (int i=0;i<colours.size()/6;i++){
+ palette.push_back(Colour(colours.substr(i*6,6)));
+ }
+ for (auto i: palette) {
+ cerr << "Signal_colour found palette colour: "<<(int)i.r<<" "<<(int)i.g<<" "<<(int)i.b<<endl;
+ }
+ prevcol=-1;
+ };
+ ~Signal_colour(){};
+ Image *output(const Frame_spec &frame){
+ if (palette.size()) {
+ if (inputs.size()) {
+ if (inputs[0]->connection){
+ int col= ((int)(((Signal_node*)inputs[0]->connection)->get_output(frame)))%palette.size();
+ if (col!=prevcol||image.w!=frame.w||image.h!=frame.h){
+ image.setup(frame.w,frame.h);
+ for (int i=0;i<image.w*image.h;i++){
+ image.RGBdata[i*3]=palette[col].r;
+ image.RGBdata[i*3+1]=palette[col].g;
+ image.RGBdata[i*3+2]=palette[col].b;
+ }
+ prevcol=col;
+ }
+ return &image;
+ }
+ }
+ }
+ return nullptr;
+ }
+ Signal_colour* clone(map<string,string> &_settings) { return new Signal_colour(_settings);};
+ private:
+ vector<Rotor::Colour> palette;
+ Image image;
+ int prevcol;
+ };
+ class Signal_greyscale: public Image_node {
+ //Draws signal bars in greyscale
+ public:
+ Signal_greyscale(){};
+ Signal_greyscale(map<string,string> &settings) {
+ base_settings(settings);
+ prevcol=-1;
+ };
+ ~Signal_greyscale(){};
+ Image *output(const Frame_spec &frame){
+ if (inputs.size()) {
+ if (inputs[0]->connection){
+ float sig= ((((Signal_node*)inputs[0]->connection)->get_output(frame)));
+ float seg=fmod(sig,(int)sig);
+ uint8_t col=255-((uint8_t)(seg*255.0f));
+ if (col!=prevcol||image.w!=frame.w||image.h!=frame.h){
+ image.setup(frame.w,frame.h);
+ for (int i=0;i<image.w*image.h*3;i++){
+ image.RGBdata[i]=col;
+ }
+ prevcol=col;
+ }
+ return &image;
+ }
+ }
+ return nullptr;
+ }
+ Signal_greyscale* clone(map<string,string> &_settings) { return new Signal_greyscale(_settings);};
+ private:
+ Image image;
+ uint8_t prevcol;
+ };
+ class Image_arithmetic: public Image_node {
+ //Draws signal bars in greyscale
+ public:
+ Image_arithmetic(){};
+ Image_arithmetic(map<string,string> &settings) {
+ base_settings(settings);
+ value=find_setting(settings,"value",0.0f);
+ string _op=find_setting(settings,"operator","+");
+ if (_op=="+") op=ARITHMETIC_plus;
+ if (_op=="-") op=ARITHMETIC_minus;
+ if (_op=="*") op=ARITHMETIC_multiply;
+ if (_op=="/") op=ARITHMETIC_divide;
+ //if (_op=="%") op=ARITHMETIC_modulo; ??what would this even mean?
+ for (auto p:parameter_inputs){
+ if (p->parameter=="value") p->receiver=&value;
+ }
+ image=nullptr;
+ };
+ ~Image_arithmetic(){if (image) delete image;};
+ Image *output(const Frame_spec &frame){
+ if (image_inputs.size()) {
+ if (image_inputs[0]->connection){
+ if (image) delete image;
+ Image *in=(((Image_node*)image_inputs[0]->connection)->get_output(frame));
+ switch (op) {
+ case ARITHMETIC_plus:
+ image=(*in)+value;
+ break;
+ case ARITHMETIC_minus:
+ image=(*in)-value;
+ break;
+ case ARITHMETIC_multiply:
+ image=(*in)*value;
+ break;
+ case ARITHMETIC_divide:
+ image=(*in)/value;
+ break;
+ }
+ return image;
+ }
+ }
+ return nullptr;
+ }
+ Image_arithmetic* clone(map<string,string> &_settings) { return new Image_arithmetic(_settings);};
+ private:
+ Image *image;
+ float value;
+ int op;
+ };
+
class Luma_levels: public Image_node {
//applies LUT To RGB channels equally
public:
@@ -839,8 +1016,12 @@ namespace Rotor {
if (fless(1.0f,fadeto)){
float amount=((((float)number-i)/number)*(1.0f-fadeto))+(1.0f-fadeto);
Image *temp=*images[absframe]*amount;
- if (mode<0.5) (*image)+=*temp;
- else (*image)=image->add_wrap(*temp);
+ if (mode<0.5) {
+ (*image)+=*temp;
+ }
+ else {
+ image->add_wrap(*temp);
+ }
delete temp;
}
else {