summaryrefslogtreecommitdiff
path: root/rotord
diff options
context:
space:
mode:
authorTim Redfern <tim@herge.(none)>2013-05-10 17:51:45 +0100
committerTim Redfern <tim@herge.(none)>2013-05-10 17:51:45 +0100
commit574c15ebe9989d079eee42b9cee4be19333fe24e (patch)
tree7dedf5f80fa064b6661670cc014869bffcd9310e /rotord
parentef8e5b1a427b473543fe3c38819d2cef4ee019b2 (diff)
echo trails almost working (?)
Diffstat (limited to 'rotord')
-rwxr-xr-xrotord/rotor.h88
1 files changed, 63 insertions, 25 deletions
diff --git a/rotord/rotor.h b/rotord/rotor.h
index 407d57c..60138fe 100755
--- a/rotord/rotor.h
+++ b/rotord/rotor.h
@@ -124,6 +124,8 @@ namespace Rotor {
class Frame_spec: public Time_spec{
public:
Frame_spec(float _time,float _framerate,int _w,int _h){ time=_time; framerate=_framerate; w=_w; h=_h;};
+ Frame_spec(int _frame,float _framerate,int _w,int _h){ time=((float)_frame)/framerate; framerate=_framerate; w=_w; h=_h;};
+
//float time; //this hould probably be implemented with a num/denom scheme eventually for accuracy
//float framerate;
int h,w;
@@ -187,13 +189,20 @@ namespace Rotor {
}
return false;
}
+ Image* clone(){
+ Image *t=new Image(w,h);
+ for (int i=0;i<w*h*3;i++) {
+ t->RGBdata[i]=RGBdata[i];
+ }
+ return t;
+ }
Image & operator+=(const Image &other) {
if (other.w!=w||other.h!=h) {
- cerr<<"Rotor: cannot add images with different sizes!"<<endl;
+ cerr<<"Rotor: cannot add images with different sizes! (wanted "<<w<<"x"<<h<<", got "<<other.w<<"x"<<other.h<<")"<<endl;
}
else {
for (int i=0;i<w*h*3;i++){
- RGBdata[i]+=other.RGBdata[i];
+ RGBdata[i]=(unsigned char)(((int)other.RGBdata[i]+(int)RGBdata[i])&0x00FF);
}
}
return *this;
@@ -532,7 +541,7 @@ namespace Rotor {
LUT=nullptr;
generate_LUT();
}
- void generate_LUT(){
+ void generate_LUT(){ //check this
if (LUT) delete[] LUT;
LUT=new unsigned char[256];
float fltmax=(255.0f/256.0f);
@@ -540,15 +549,20 @@ namespace Rotor {
LUT[i]=(unsigned char)(((pow(min(fltmax,max(0.0f,(((((float)i)/256.0f)-black_in)/(white_in-black_in)))),(1.0/gamma))*(white_out-black_out))+black_out)*256.0f);
}
}
+ void apply_LUT(const Image& in){
+ apply_LUT(in,*image);
+ }
+ void apply_LUT(const Image& in,Image &out){ //facility to apply to other images for ingherited classes
+ out.setup(in.w,in.h);
+ for (int i=0;i<out.w*out.h*3;i++){
+ out.RGBdata[i]=LUT[in.RGBdata[i]];
+ }
+ }
Image *get_output(const Frame_spec &frame){
- image->setup(frame.w,frame.h);
if (image_inputs.size()) {
if (image_inputs[0]->connection){
if (LUT) {
- Image *in= (((Image_node*)image_inputs[0]->connection)->get_output(frame));
- for (int i=0;i<frame.w*frame.h*3;i++){
- image->RGBdata[i]=LUT[in->RGBdata[i]];
- }
+ apply_LUT(*(((Image_node*)image_inputs[0]->connection)->get_output(frame)));
return image;
}
}
@@ -564,7 +578,7 @@ namespace Rotor {
};
class Echo_trails: public Luma_levels {
//draw trail frames additively that fade off over time
- //the hard thing here is how to cache frames, if its done cleverly it could have no impact when
+ //the hard thing here is how to cache frames, if its done cleverly it could have no impact when
//used linearly
//Image needs to overload operator+
//need a clever data structure to cache frames - maybe a map of Image pointers
@@ -598,17 +612,16 @@ namespace Rotor {
number=find_setting(settings,"number",1);
levels_settings(settings);
image=new Image();
- w=h=0;
+ lastframe=-1;
};
~Echo_trails(){if (image) {delete image;} };
Image *get_output(const Frame_spec &frame){
- //cache frames
- if (frame.w!=w||frame.h!=h){ //or framerate changed?
+ //check if cache is valid
+ if (frame.w!=image->w||frame.h!=image->h){ //or framerate changed?
//clear cache and start over
images.clear();
+ lastframe=-1;
//calculate frame interval
- w=frame.w;
- h=frame.h;
interval=(int)((duration/number)*frame.framerate);
total=interval*number;
}
@@ -623,15 +636,40 @@ namespace Rotor {
++i;
}
//if frame has already been calculated just return it
- if (image) delete image;
- if (image_inputs.size()) {
- if (image_inputs[0]->connection){
- if (LUT) {
- (*image)= *(((Image_node*)image_inputs[0]->connection)->get_output(frame));
- for (int i=0;i<frame.w*frame.h*3;i++){
- image->RGBdata[i]=LUT[in->RGBdata[i]];
+ if (thisframe==lastframe) {
+ return image;
+ }
+ else {
+ if (image_inputs.size()) {
+ if (image_inputs[0]->connection){
+ if (LUT) {
+ //copy incoming image **writable
+ image->free();
+ image=(((Image_node*)image_inputs[0]->connection)->get_output(frame))->clone();
+ for (int i=0;i<number;i++){
+ //check echo frame isn't at negative time
+ int absframe=thisframe-(i*interval);
+ if (absframe>-1){
+ //check if image is in the cache
+ if (images.find(absframe)==images.end()){
+ //cerr<<"Rotor: preparing image ("<<image->w<<"x"<<image->h<<")"<<endl;
+
+ images[absframe]=new Image(image->w,image->h);
+ //cerr<<"Rotor: prepared image ("<<images[absframe].w<<"x"<<images[absframe].h<<")"<<endl;
+
+ Frame_spec wanted=Frame_spec(absframe,frame.framerate,frame.w,frame.h);
+ apply_LUT(*(((Image_node*)image_inputs[0]->connection)->get_output(wanted)),*images[absframe]);
+ }
+ //cerr<<"Rotor: about to apply image ("<<images[absframe].w<<"x"<<images[absframe].h<<")"<<endl;
+ (*image)+=*images[absframe];
+ }
+ }
+ //for (int i=0;i<frame.w*frame.h*3;i++){
+ // image->RGBdata[i]=LUT[in->RGBdata[i]];
+ //}
+ lastframe=thisframe;
+ return image;
}
- return image;
}
}
}
@@ -640,9 +678,9 @@ namespace Rotor {
Echo_trails* clone(map<string,string> &_settings) { return new Echo_trails(_settings);};
private:
float duration;
- int number,w,h;
- int interval,total; //number of frames between displayed echoes
- unordered_map<int,Image> images;
+ int number;
+ int interval,total,lastframe; //number of frames between displayed echoes
+ unordered_map<int,Image*> images;
};
//-------------------------------------------------------------------
class Node_factory{