TuttleOFX  1
channels.hpp
Go to the documentation of this file.
00001 #ifndef _channels_hpp_
00002 #define _channels_hpp_
00003 
00004 #include <assert.h>
00005 #include <boost/gil/gil_all.hpp>
00006 #include <boost/function.hpp>
00007 
00008 struct channels
00009 {
00010         struct channel
00011         {
00012                 int pos;
00013                 channel* next;
00014         };
00015 
00016         channel* head;
00017         channel* current;
00018 
00019         channels() : head(NULL), current(NULL) {}
00020         channels(channel* head) : head(head), current(head) {}
00021         operator bool (){return current != NULL;}
00022         operator channel * () {return head;}
00023         double operator *(){return current->pos;}
00024         void operator ++(int){current = current->next;}
00025         void operator ++(){current = current->next;}
00026         void reset() {current = head;}
00027 
00028         ~channels()
00029         {
00030                 while (head)
00031                 {
00032                         channel* tmp = head->next;
00033                         free(head);
00034                         head = tmp;
00035                 }
00036                 
00037                 head = NULL;
00038         }
00039 
00040         channels(int width, int channels)
00041         {
00042                 assert(channels);
00043                 assert(width);
00044         
00045                 head = (channel*)malloc(sizeof(channel));
00046                 
00047                 head->pos = width-1;
00048                 head->next = NULL;
00049                 
00050                 if (channels != 1)
00051                 {
00052                         head->pos = -1;
00053                         channel* save_head = head;
00054                         
00055                         --channels;     
00056                         int adj = width/channels;
00057                         int extra = 0;
00058                         if (width % channels)
00059                                 extra = width-adj*channels;
00060                 
00061                         while (head->pos < width-1)
00062                         {
00063                                 int add = adj;
00064                                 if (extra-- > 0)
00065                                         add++;
00066                 
00067                                 channel* tail  = (channel*)malloc(sizeof(channel));
00068                                 tail->pos = head->pos + add;
00069                                 tail->next = NULL;
00070                 
00071                                 head->next = tail;
00072                                 head = tail;
00073                         }
00074                 
00075                         head = save_head;
00076                         head->pos = 0;
00077 
00078                         current = head;
00079                 }
00080         }
00081 };
00082 
00083 
00084 namespace layer
00085 {
00086 
00087 //Used by the horizontal date labels
00088 template <typename view_t>
00089 struct horizontal_channels
00090 {
00091         typedef boost::function<void (view_t&)> layer_t;
00092         std::vector<layer_t> layers;
00093         int periods;
00094 
00095         horizontal_channels(layer_t* p, int size, int periods) : periods(periods)
00096         {
00097                 for (int n = 0; n < size; ++n)
00098                         layers.push_back(p[n]);
00099         }
00100 
00101         void operator()(view_t& view)
00102         {
00103                 using namespace boost::gil;
00104 
00105                 channels i(periods, layers.size());
00106                 channels x(view.width(), periods);
00107 
00108                 int n=0, m=0;
00109                 for (; i; ++i, ++m)
00110                 {
00111                         for (; n < *i; ++n, ++x);
00112 
00113                         view_t v = subimage_view(view,*x,0,0,view.height());
00114                         layers[m](v);
00115                 }
00116         }
00117 };
00118 
00119 }
00120 
00121 #endif