diff options
Diffstat (limited to 'rotord/rotor.h')
| -rwxr-xr-x | rotord/rotor.h | 185 |
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 ℑ + } + } + } + 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 ℑ + } + } + 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 { |
