Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/img

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /externals/g4tools/include/tools/img (Version 11.3.0) and /externals/g4tools/include/tools/img (Version 11.1)


  1 // Copyright (C) 2010, Guy Barrand. All rights      1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.            2 // See the file tools.license for terms.
  3                                                     3 
  4 #ifndef tools_img                                   4 #ifndef tools_img
  5 #define tools_img                                   5 #define tools_img
  6                                                     6 
  7 #ifdef TOOLS_MEM                                    7 #ifdef TOOLS_MEM
  8 #include "mem"                                      8 #include "mem"
  9 #endif                                              9 #endif
 10                                                    10 
 11 #include <string> //memcpy                         11 #include <string> //memcpy
 12 #include <cstring> //memcpy                        12 #include <cstring> //memcpy
 13 #include "mnmx"                                    13 #include "mnmx"
 14 #include "S_STRING"                                14 #include "S_STRING"
 15                                                    15 
 16 #include <vector> //concatenate                    16 #include <vector> //concatenate
 17                                                    17 
 18 namespace tools {                                  18 namespace tools {
 19                                                    19 
 20 template <class T>                                 20 template <class T>
 21 class img {                                        21 class img {
 22 public:                                            22 public:
 23   TOOLS_T_SCLASS(T,tools::img)                     23   TOOLS_T_SCLASS(T,tools::img)
 24 public:                                            24 public:
 25   img()                                            25   img()
 26   :m_w(0),m_h(0),m_n(0)                            26   :m_w(0),m_h(0),m_n(0)
 27   ,m_buffer(0)                                     27   ,m_buffer(0)
 28   ,m_owner(false)                                  28   ,m_owner(false)
 29   {                                                29   {
 30 #ifdef TOOLS_MEM                                   30 #ifdef TOOLS_MEM
 31     mem::increment(s_class().c_str());             31     mem::increment(s_class().c_str());
 32 #endif                                             32 #endif
 33   }                                                33   }
 34   img(unsigned int a_w,unsigned int a_h,unsign     34   img(unsigned int a_w,unsigned int a_h,unsigned int a_n,T* a_buffer,bool a_owner)
 35   :m_w(a_w),m_h(a_h),m_n(a_n)                      35   :m_w(a_w),m_h(a_h),m_n(a_n)
 36   ,m_buffer(a_buffer)                              36   ,m_buffer(a_buffer)
 37   ,m_owner(a_owner)                                37   ,m_owner(a_owner)
 38   {                                                38   {
 39 #ifdef TOOLS_MEM                                   39 #ifdef TOOLS_MEM
 40     mem::increment(s_class().c_str());             40     mem::increment(s_class().c_str());
 41 #endif                                             41 #endif
 42   }                                                42   }
 43   virtual ~img() {                                 43   virtual ~img() {
 44     if(m_owner) delete [] m_buffer;                44     if(m_owner) delete [] m_buffer;
 45 #ifdef TOOLS_MEM                                   45 #ifdef TOOLS_MEM
 46     mem::decrement(s_class().c_str());             46     mem::decrement(s_class().c_str());
 47 #endif                                             47 #endif
 48   }                                                48   }
 49 public:                                            49 public:
 50   img(const img& a_from)                           50   img(const img& a_from)
 51   :m_w(a_from.m_w),m_h(a_from.m_h),m_n(a_from.     51   :m_w(a_from.m_w),m_h(a_from.m_h),m_n(a_from.m_n)
 52   ,m_buffer(0)                                     52   ,m_buffer(0)
 53   ,m_owner(a_from.m_owner)                         53   ,m_owner(a_from.m_owner)
 54   {                                                54   {
 55 #ifdef TOOLS_MEM                                   55 #ifdef TOOLS_MEM
 56     mem::increment(s_class().c_str());             56     mem::increment(s_class().c_str());
 57 #endif                                             57 #endif
 58     if(m_owner) {                                  58     if(m_owner) {
 59       unsigned int sz = m_w*m_h*m_n;               59       unsigned int sz = m_w*m_h*m_n;
 60       if(!sz) return;                              60       if(!sz) return;
 61       m_buffer = new T[sz];                        61       m_buffer = new T[sz];
 62       if(!m_buffer) {                              62       if(!m_buffer) {
 63         m_w = 0;m_h = 0;m_n = 0;m_owner = fals     63         m_w = 0;m_h = 0;m_n = 0;m_owner = false;
 64         return; //throw                            64         return; //throw
 65       }                                            65       }
 66       ::memcpy(m_buffer,a_from.m_buffer,sz*siz     66       ::memcpy(m_buffer,a_from.m_buffer,sz*sizeof(T));
 67     } else {                                       67     } else {
 68       m_buffer = a_from.m_buffer;                  68       m_buffer = a_from.m_buffer;
 69     }                                              69     }
 70   }                                                70   }
 71   img& operator=(const img& a_from){               71   img& operator=(const img& a_from){
 72     if(&a_from==this) return *this;                72     if(&a_from==this) return *this;
 73     if(m_owner) delete [] m_buffer;                73     if(m_owner) delete [] m_buffer;
 74     m_buffer = 0;                                  74     m_buffer = 0;
 75     m_w = a_from.m_w;                              75     m_w = a_from.m_w;
 76     m_h = a_from.m_h;                              76     m_h = a_from.m_h;
 77     m_n = a_from.m_n;                              77     m_n = a_from.m_n;
 78     m_owner = a_from.m_owner;                      78     m_owner = a_from.m_owner;
 79     if(m_owner) {                                  79     if(m_owner) {
 80       unsigned int sz = m_w*m_h*m_n;               80       unsigned int sz = m_w*m_h*m_n;
 81       if(!sz) return *this;                        81       if(!sz) return *this;
 82       m_buffer = new T[sz];                        82       m_buffer = new T[sz];
 83       if(!m_buffer) {                              83       if(!m_buffer) {
 84         m_w = 0;m_h = 0;m_n = 0;m_owner = fals     84         m_w = 0;m_h = 0;m_n = 0;m_owner = false;
 85         return *this;  //throw                     85         return *this;  //throw
 86       }                                            86       }
 87       ::memcpy(m_buffer,a_from.m_buffer,sz*siz     87       ::memcpy(m_buffer,a_from.m_buffer,sz*sizeof(T));
 88     } else {                                       88     } else {
 89       m_buffer = a_from.m_buffer;                  89       m_buffer = a_from.m_buffer;
 90     }                                              90     }
 91     return *this;                                  91     return *this;
 92   }                                                92   }
 93 public:                                            93 public:
 94   bool operator==(const img& a_from) const {re     94   bool operator==(const img& a_from) const {return equal(a_from);}
 95   bool operator!=(const img& a_from) const {re     95   bool operator!=(const img& a_from) const {return !operator==(a_from);}
 96 public:                                            96 public:
 97   void transfer(img& a_from) {                     97   void transfer(img& a_from) {
 98     if(m_owner) delete [] m_buffer;                98     if(m_owner) delete [] m_buffer;
 99     m_w = a_from.m_w;                              99     m_w = a_from.m_w;
100     m_h = a_from.m_h;                             100     m_h = a_from.m_h;
101     m_n = a_from.m_n;                             101     m_n = a_from.m_n;
102     m_buffer = a_from.m_buffer;                   102     m_buffer = a_from.m_buffer;
103     m_owner = a_from.m_owner;                     103     m_owner = a_from.m_owner;
104     // empty a_from :                             104     // empty a_from :
105     a_from.m_w = 0;                               105     a_from.m_w = 0;
106     a_from.m_h = 0;                               106     a_from.m_h = 0;
107     a_from.m_buffer = 0;                          107     a_from.m_buffer = 0;
108     a_from.m_owner = false;                       108     a_from.m_owner = false;
109   }                                               109   }
110                                                   110 
111   void clear() {                                  111   void clear() {
112     if(m_owner) delete [] m_buffer;               112     if(m_owner) delete [] m_buffer;
113     m_w = 0;                                      113     m_w = 0;
114     m_h = 0;                                      114     m_h = 0;
115     m_n = 0;                                      115     m_n = 0;
116     m_buffer = 0;                                 116     m_buffer = 0;
117     m_owner = false;                              117     m_owner = false;
118   }                                               118   }
119   void set(unsigned int a_w,unsigned int a_h,u    119   void set(unsigned int a_w,unsigned int a_h,unsigned int a_n,T* a_buffer,bool a_owner) {
120     if(m_owner) delete [] m_buffer;               120     if(m_owner) delete [] m_buffer;
121     m_w = a_w;                                    121     m_w = a_w;
122     m_h = a_h;                                    122     m_h = a_h;
123     m_n = a_n;                                    123     m_n = a_n;
124     m_buffer = a_buffer;                          124     m_buffer = a_buffer;
125     m_owner = a_owner;                            125     m_owner = a_owner;
126   }                                               126   }
127   bool copy(unsigned int a_w,unsigned int a_h,    127   bool copy(unsigned int a_w,unsigned int a_h,unsigned int a_n,T* a_buffer) {
128     if(m_owner) delete [] m_buffer;               128     if(m_owner) delete [] m_buffer;
129     m_buffer = 0;                                 129     m_buffer = 0;
130     m_w = a_w;                                    130     m_w = a_w;
131     m_h = a_h;                                    131     m_h = a_h;
132     m_n = a_n;                                    132     m_n = a_n;
133     unsigned int sz = m_w*m_h*m_n;                133     unsigned int sz = m_w*m_h*m_n;
134     if(!sz) {                                     134     if(!sz) {
135       m_w = 0;m_h = 0;m_n = 0;m_owner = false;    135       m_w = 0;m_h = 0;m_n = 0;m_owner = false;
136       return false;                               136       return false;
137     }                                             137     }
138     m_buffer = new T[sz];                         138     m_buffer = new T[sz];
139     if(!m_buffer) {                               139     if(!m_buffer) {
140       m_w = 0;m_h = 0;m_n = 0;m_owner = false;    140       m_w = 0;m_h = 0;m_n = 0;m_owner = false;
141       return false;                               141       return false;
142     }                                             142     }
143     ::memcpy(m_buffer,a_buffer,sz*sizeof(T));     143     ::memcpy(m_buffer,a_buffer,sz*sizeof(T));
144     m_owner = true;                               144     m_owner = true;
145     return true;                                  145     return true;
146   }                                               146   }
147   bool copy(const img& a_from){                   147   bool copy(const img& a_from){
148     if(m_owner) delete [] m_buffer;               148     if(m_owner) delete [] m_buffer;
149     m_buffer = 0;                                 149     m_buffer = 0;
150     m_w = a_from.m_w;                             150     m_w = a_from.m_w;
151     m_h = a_from.m_h;                             151     m_h = a_from.m_h;
152     m_n = a_from.m_n;                             152     m_n = a_from.m_n;
153     unsigned int sz = m_w*m_h*m_n;                153     unsigned int sz = m_w*m_h*m_n;
154     if(!sz) {                                     154     if(!sz) {
155       m_w = 0;m_h = 0;m_n = 0;m_owner = false;    155       m_w = 0;m_h = 0;m_n = 0;m_owner = false;
156       return false;                               156       return false;
157     }                                             157     }
158     m_buffer = new T[sz];                         158     m_buffer = new T[sz];
159     if(!m_buffer) {                               159     if(!m_buffer) {
160       m_w = 0;m_h = 0;m_n = 0;m_owner = false;    160       m_w = 0;m_h = 0;m_n = 0;m_owner = false;
161       return false;                               161       return false;
162     }                                             162     }
163     ::memcpy(m_buffer,a_from.m_buffer,sz*sizeo    163     ::memcpy(m_buffer,a_from.m_buffer,sz*sizeof(T));
164     m_owner = true;                               164     m_owner = true;
165     return true;                                  165     return true;
166   }                                               166   }
167   bool allocate(unsigned int a_w,unsigned int     167   bool allocate(unsigned int a_w,unsigned int a_h,unsigned int a_n){
168     if(m_owner) delete [] m_buffer;               168     if(m_owner) delete [] m_buffer;
169     m_buffer = 0;                                 169     m_buffer = 0;
170     unsigned int sz = a_w*a_h*a_n;                170     unsigned int sz = a_w*a_h*a_n;
171     if(!sz) {                                     171     if(!sz) {
172       m_w = 0;m_h = 0;m_n = 0;m_owner = false;    172       m_w = 0;m_h = 0;m_n = 0;m_owner = false;
173       return false;                               173       return false;
174     }                                             174     }
175     m_w = a_w;                                    175     m_w = a_w;
176     m_h = a_h;                                    176     m_h = a_h;
177     m_n = a_n;                                    177     m_n = a_n;
178     m_buffer = new T[sz];                         178     m_buffer = new T[sz];
179     if(!m_buffer) {                               179     if(!m_buffer) {
180       m_w = 0;m_h = 0;m_n = 0;m_owner = false;    180       m_w = 0;m_h = 0;m_n = 0;m_owner = false;
181       return false;                               181       return false;
182     }                                             182     }
183     m_owner = true;                               183     m_owner = true;
184     return true;                                  184     return true;
185   }                                               185   }
186   void make_empty(bool a_delete = true) {         186   void make_empty(bool a_delete = true) {
187     if(m_owner && a_delete) delete [] m_buffer    187     if(m_owner && a_delete) delete [] m_buffer;
188     m_w = 0;                                      188     m_w = 0;
189     m_h = 0;                                      189     m_h = 0;
190     m_n = 0;                                      190     m_n = 0;
191     m_buffer = 0;                                 191     m_buffer = 0;
192     m_owner = false;                              192     m_owner = false;
193   }                                               193   }
194   bool is_empty() const {                         194   bool is_empty() const {
195     if(!m_w) return true;                         195     if(!m_w) return true;
196     if(!m_h) return true;                         196     if(!m_h) return true;
197     if(!m_n) return true;                         197     if(!m_n) return true;
198     if(!m_buffer) return true;                    198     if(!m_buffer) return true;
199     return false;                                 199     return false;
200   }                                               200   }
201   bool equal(const img& a_from) const {           201   bool equal(const img& a_from) const {
202     if(m_w!=a_from.m_w) return false;             202     if(m_w!=a_from.m_w) return false;
203     if(m_h!=a_from.m_h) return false;             203     if(m_h!=a_from.m_h) return false;
204     if(m_n!=a_from.m_n) return false;             204     if(m_n!=a_from.m_n) return false;
205     //don't test ownership.                       205     //don't test ownership.
206     unsigned int sz = m_w*m_h*m_n;                206     unsigned int sz = m_w*m_h*m_n;
207     T* pos = m_buffer;                            207     T* pos = m_buffer;
208     T* fpos = a_from.m_buffer;                    208     T* fpos = a_from.m_buffer;
209     for(unsigned int index=0;index<sz;index++,    209     for(unsigned int index=0;index<sz;index++,pos++,fpos++) {
210       if((*pos)!=(*fpos)) return false;           210       if((*pos)!=(*fpos)) return false;
211     }                                             211     }
212     return true;                                  212     return true;
213   }                                               213   }
214   unsigned int width() const {return m_w;}        214   unsigned int width() const {return m_w;}
215   unsigned int height() const {return m_h;}       215   unsigned int height() const {return m_h;}
216   unsigned int bytes_per_pixel() const {return    216   unsigned int bytes_per_pixel() const {return m_n;}
217   unsigned int bpp() const {return m_n;}          217   unsigned int bpp() const {return m_n;}
218   const T* buffer() const {return m_buffer;}      218   const T* buffer() const {return m_buffer;}
219   T* buffer() {return m_buffer;}                  219   T* buffer() {return m_buffer;}
220   bool owner() const {return m_owner;}            220   bool owner() const {return m_owner;}
221   unsigned int size() const {return m_w*m_h*m_    221   unsigned int size() const {return m_w*m_h*m_n*sizeof(T);} //bytes.
222 public:                                           222 public:
223   bool pixel(unsigned int a_i,unsigned a_j,std    223   bool pixel(unsigned int a_i,unsigned a_j,std::vector<T>& a_pixel) const {
224     if((!m_w)||(!m_h)||(a_i>=m_w)||(a_j>=m_h))    224     if((!m_w)||(!m_h)||(a_i>=m_w)||(a_j>=m_h)) {
225       a_pixel.clear();                            225       a_pixel.clear();
226       return false;                               226       return false;
227     }                                             227     }
228     a_pixel.resize(m_n);                          228     a_pixel.resize(m_n);
229     T* pos = m_buffer + a_j * (m_w * m_n) + a_    229     T* pos = m_buffer + a_j * (m_w * m_n) + a_i*m_n;
230     for(unsigned int ipix=0;ipix<m_n;ipix++) {    230     for(unsigned int ipix=0;ipix<m_n;ipix++) {
231       a_pixel[ipix] = *(pos+ipix);                231       a_pixel[ipix] = *(pos+ipix);
232     }                                             232     }
233     return true;                                  233     return true;
234   }                                               234   }
235                                                   235 
236   bool expand(unsigned int a_factor,img<T>& a_    236   bool expand(unsigned int a_factor,img<T>& a_res,bool a_res_force_owner = true) const {
237     if(a_factor==1) {                             237     if(a_factor==1) {
238       if(a_res_force_owner) {                     238       if(a_res_force_owner) {
239         a_res.copy(m_w,m_h,m_n,m_buffer);         239         a_res.copy(m_w,m_h,m_n,m_buffer);
240       } else {                                    240       } else {
241         a_res.set(m_w,m_h,m_n,m_buffer,false);    241         a_res.set(m_w,m_h,m_n,m_buffer,false);
242       }                                           242       }
243       return true;                                243       return true;
244     }                                             244     }
245                                                   245 
246     unsigned int nw = m_w*a_factor;               246     unsigned int nw = m_w*a_factor;
247     unsigned int nh = m_h*a_factor;               247     unsigned int nh = m_h*a_factor;
248     unsigned int sz = nh*nw*m_n;                  248     unsigned int sz = nh*nw*m_n;
249     if(!sz) {                                     249     if(!sz) {
250       a_res.make_empty();                         250       a_res.make_empty();
251       return false;                               251       return false;
252     }                                             252     }
253                                                   253 
254     T* nb = new T[sz];                            254     T* nb = new T[sz];
255     if(!nb) {                                     255     if(!nb) {
256       a_res.make_empty();                         256       a_res.make_empty();
257       return false;                               257       return false;
258     }                                             258     }
259                                                   259 
260     for(unsigned int j=0;j<m_h;j++) {             260     for(unsigned int j=0;j<m_h;j++) {
261       for(unsigned int i=0;i<m_w;i++) {           261       for(unsigned int i=0;i<m_w;i++) {
262         //position in the original image.         262         //position in the original image.
263         T* pos = m_buffer + j * (m_w * m_n) +     263         T* pos = m_buffer + j * (m_w * m_n) + i*m_n;
264                                                   264 
265         for(unsigned int fr=0;fr<a_factor;fr++    265         for(unsigned int fr=0;fr<a_factor;fr++) {
266           for(unsigned int fc=0;fc<a_factor;fc    266           for(unsigned int fc=0;fc<a_factor;fc++) {
267             //position in the new image.          267             //position in the new image.
268             T* npos = nb + (j*a_factor+fr) * (    268             T* npos = nb + (j*a_factor+fr) * (nw * m_n) + (i*a_factor+fc)*m_n;
269             for(unsigned int ipix=0;ipix<m_n;i    269             for(unsigned int ipix=0;ipix<m_n;ipix++) {
270               *(npos+ipix) = *(pos+ipix);         270               *(npos+ipix) = *(pos+ipix);
271             }                                     271             }
272           }                                       272           }
273         }                                         273         }
274                                                   274 
275       }                                           275       }
276     }                                             276     }
277                                                   277 
278     a_res.set(nw,nh,m_n,nb,true);                 278     a_res.set(nw,nh,m_n,nb,true);
279     return true;                                  279     return true;
280   }                                               280   }
281                                                   281 
282   bool contract_raw(unsigned int a_w,unsigned     282   bool contract_raw(unsigned int a_w,unsigned int a_h,img<T>& a_res,bool a_force_res_owner = true) const {
283     if((a_w==m_w)&&(a_h==m_h)) {                  283     if((a_w==m_w)&&(a_h==m_h)) {
284       if(a_force_res_owner) {                     284       if(a_force_res_owner) {
285         a_res.copy(m_w,m_h,m_n,m_buffer);         285         a_res.copy(m_w,m_h,m_n,m_buffer);
286       } else {                                    286       } else {
287         a_res.set(m_w,m_h,m_n,m_buffer,false);    287         a_res.set(m_w,m_h,m_n,m_buffer,false);
288       }                                           288       }
289       return true;                                289       return true;
290     }                                             290     }
291                                                   291 
292     unsigned int sz = a_h*a_w*m_n;                292     unsigned int sz = a_h*a_w*m_n;
293     if(!sz) {                                     293     if(!sz) {
294       a_res.make_empty();                         294       a_res.make_empty();
295       return false;                               295       return false;
296     }                                             296     }
297                                                   297 
298     T* rb = new T[sz];                            298     T* rb = new T[sz];
299     if(!rb) {                                     299     if(!rb) {
300       a_res.make_empty();                         300       a_res.make_empty();
301       return false;                               301       return false;
302     }                                             302     }
303                                                   303 
304     double* pixels = new double[m_n]; //for me    304     double* pixels = new double[m_n]; //for mean value.
305     if(!pixels) {                                 305     if(!pixels) {
306       delete [] rb;                               306       delete [] rb;
307       a_res.make_empty();                         307       a_res.make_empty();
308       return false;                               308       return false;
309     }                                             309     }
310                                                   310 
311     unsigned int wfac = double(m_w)/double(a_w    311     unsigned int wfac = double(m_w)/double(a_w);
312     unsigned int hfac = double(m_h)/double(a_h    312     unsigned int hfac = double(m_h)/double(a_h);
313     if(!wfac) wfac = 1;                           313     if(!wfac) wfac = 1;
314     if(!hfac) hfac = 1;                           314     if(!hfac) hfac = 1;
315                                                   315 
316     unsigned int wfac_hfac = wfac*hfac;           316     unsigned int wfac_hfac = wfac*hfac;
317                                                   317 
318     T* hpos;T* pos;                               318     T* hpos;T* pos;
319     for(unsigned int j=0;j<a_h;j++) {             319     for(unsigned int j=0;j<a_h;j++) {
320       for(unsigned int i=0;i<a_w;i++) {           320       for(unsigned int i=0;i<a_w;i++) {
321                                                   321 
322         // take mean value of wfac*hfac pixels    322         // take mean value of wfac*hfac pixels :
323        {for(unsigned int ipix=0;ipix<m_n;ipix+    323        {for(unsigned int ipix=0;ipix<m_n;ipix++) pixels[ipix] = 0;}
324                                                   324 
325         for(unsigned int fr=0;fr<hfac;fr++) {     325         for(unsigned int fr=0;fr<hfac;fr++) {
326           hpos = m_buffer + (j*hfac+fr)*(m_w*m    326           hpos = m_buffer + (j*hfac+fr)*(m_w*m_n);
327           for(unsigned int fc=0;fc<wfac;fc++)     327           for(unsigned int fc=0;fc<wfac;fc++) {
328             pos = hpos + (i*wfac+fc)*m_n;         328             pos = hpos + (i*wfac+fc)*m_n;
329             for(unsigned int ipix=0;ipix<m_n;i    329             for(unsigned int ipix=0;ipix<m_n;ipix++) {
330               pixels[ipix] += double(*pos)/dou    330               pixels[ipix] += double(*pos)/double(wfac_hfac);pos++;
331             }                                     331             }
332           }                                       332           }
333         }                                         333         }
334                                                   334 
335         //position in the result image.           335         //position in the result image.
336         T* rpos = rb + j * (a_w * m_n) + i*m_n    336         T* rpos = rb + j * (a_w * m_n) + i*m_n;
337        {for(unsigned int ipix=0;ipix<m_n;ipix+    337        {for(unsigned int ipix=0;ipix<m_n;ipix++) {*rpos = T(pixels[ipix]);rpos++;}}
338       }                                           338       }
339     }                                             339     }
340                                                   340 
341     delete [] pixels;                             341     delete [] pixels;
342                                                   342 
343     a_res.set(a_w,a_h,m_n,rb,true);               343     a_res.set(a_w,a_h,m_n,rb,true);
344     return true;                                  344     return true;
345   }                                               345   }
346                                                   346 
347   bool contract(unsigned int a_w,unsigned int     347   bool contract(unsigned int a_w,unsigned int a_h,img<T>& a_res,bool a_force_res_owner = true) const {
348     //optimized version of contract_raw().        348     //optimized version of contract_raw().
349                                                   349 
350     if((a_w==m_w)&&(a_h==m_h)) {                  350     if((a_w==m_w)&&(a_h==m_h)) {
351       if(a_force_res_owner) {                     351       if(a_force_res_owner) {
352         a_res.copy(m_w,m_h,m_n,m_buffer);         352         a_res.copy(m_w,m_h,m_n,m_buffer);
353       } else {                                    353       } else {
354         a_res.set(m_w,m_h,m_n,m_buffer,false);    354         a_res.set(m_w,m_h,m_n,m_buffer,false);
355       }                                           355       }
356       return true;                                356       return true;
357     }                                             357     }
358                                                   358 
359     size_t sz = a_h*a_w*m_n;                      359     size_t sz = a_h*a_w*m_n;
360     if(!sz) {                                     360     if(!sz) {
361       a_res.make_empty();                         361       a_res.make_empty();
362       return false;                               362       return false;
363     }                                             363     }
364                                                   364 
365     T* rb = new T[sz];                            365     T* rb = new T[sz];
366     if(!rb) {                                     366     if(!rb) {
367       a_res.make_empty();                         367       a_res.make_empty();
368       return false;                               368       return false;
369     }                                             369     }
370                                                   370 
371     double* pixels = new double[m_n]; //for me    371     double* pixels = new double[m_n]; //for mean value.
372     if(!pixels) {                                 372     if(!pixels) {
373       delete [] rb;                               373       delete [] rb;
374       a_res.make_empty();                         374       a_res.make_empty();
375       return false;                               375       return false;
376     }                                             376     }
377    {for(unsigned int ipix=0;ipix<m_n;ipix++) p    377    {for(unsigned int ipix=0;ipix<m_n;ipix++) pixels[ipix] = 0;}
378                                                   378 
379     unsigned int wfac = (unsigned int)(double(    379     unsigned int wfac = (unsigned int)(double(m_w)/double(a_w));
380     unsigned int hfac = (unsigned int)(double(    380     unsigned int hfac = (unsigned int)(double(m_h)/double(a_h));
381     if(!wfac) wfac = 1;                           381     if(!wfac) wfac = 1;
382     if(!hfac) hfac = 1;                           382     if(!hfac) hfac = 1;
383                                                   383 
384     double wfac_hfac = wfac*hfac;                 384     double wfac_hfac = wfac*hfac;
385                                                   385 
386     //::printf("debug : %d %d, %d %d\n",a_h,a_    386     //::printf("debug : %d %d, %d %d\n",a_h,a_w,hfac,wfac);
387                                                   387 
388     T* hpos;T* pos;T* hrpos;T* rpos;T* hhpos;T    388     T* hpos;T* pos;T* hrpos;T* rpos;T* hhpos;T* _pos;double* ppos;
389     unsigned int i,j,fr,fc,ipix,i0;               389     unsigned int i,j,fr,fc,ipix,i0;
390     unsigned int astride = a_w * m_n;             390     unsigned int astride = a_w * m_n;
391     unsigned int mstride = m_w * m_n;             391     unsigned int mstride = m_w * m_n;
392     unsigned int wfacstride = wfac * m_n;         392     unsigned int wfacstride = wfac * m_n;
393                                                   393 
394     for(j=0;j<a_h;j++) {                          394     for(j=0;j<a_h;j++) {
395       hrpos = rb + j * astride;                   395       hrpos = rb + j * astride;
396       hhpos = m_buffer + j*hfac*mstride;          396       hhpos = m_buffer + j*hfac*mstride;
397       for(i=0;i<a_w;i++) {                        397       for(i=0;i<a_w;i++) {
398                                                   398 
399         // take mean value of wfac*hfac pixels    399         // take mean value of wfac*hfac pixels :
400                                                   400 
401         i0 = i*wfacstride;                        401         i0 = i*wfacstride;
402                                                   402 
403         hpos = hhpos;                             403         hpos = hhpos;
404         for(fr=0;fr<hfac;fr++,hpos+=mstride) {    404         for(fr=0;fr<hfac;fr++,hpos+=mstride) {
405           _pos = hpos + i0;                       405           _pos = hpos + i0;
406           for(fc=0;fc<wfac;fc++,_pos+=m_n) {      406           for(fc=0;fc<wfac;fc++,_pos+=m_n) {
407             pos = _pos;                           407             pos = _pos;
408             ppos = pixels;                        408             ppos = pixels;
409             for(ipix=0;ipix<m_n;ipix++,pos++,p    409             for(ipix=0;ipix<m_n;ipix++,pos++,ppos++) {
410               *ppos += double(*pos)/wfac_hfac;    410               *ppos += double(*pos)/wfac_hfac;
411 //              *ppos += double(*pos); //NOTE     411 //              *ppos += double(*pos); //NOTE : doing the wfac_hfac division in the below loop is slower !
412             }                                     412             }
413           }                                       413           }
414         }                                         414         }
415                                                   415 
416         //position in the result image.           416         //position in the result image.
417         rpos = hrpos + i*m_n;                     417         rpos = hrpos + i*m_n;
418         ppos = pixels;                            418         ppos = pixels;
419         for(ipix=0;ipix<m_n;ipix++,rpos++,ppos    419         for(ipix=0;ipix<m_n;ipix++,rpos++,ppos++) {
420           *rpos = T(*ppos);                       420           *rpos = T(*ppos);
421 //          *rpos = T((*ppos)/wfac_hfac); //sl    421 //          *rpos = T((*ppos)/wfac_hfac); //slower !
422           *ppos = 0;                              422           *ppos = 0;
423         }                                         423         }
424       }                                           424       }
425     }                                             425     }
426                                                   426 
427     delete [] pixels;                             427     delete [] pixels;
428                                                   428 
429     a_res.set(a_w,a_h,m_n,rb,true);               429     a_res.set(a_w,a_h,m_n,rb,true);
430     return true;                                  430     return true;
431   }                                               431   }
432                                                   432 
433   bool contract(unsigned int a_factor,img<T>&     433   bool contract(unsigned int a_factor,img<T>& a_res,bool a_force_res_owner = true) const {
434     // a_factor pixels are contracted in one.     434     // a_factor pixels are contracted in one.
435     unsigned int nw = m_w/a_factor;               435     unsigned int nw = m_w/a_factor;
436     unsigned int nh = m_h/a_factor;               436     unsigned int nh = m_h/a_factor;
437     return contract(nw,nh,a_res,a_force_res_ow    437     return contract(nw,nh,a_res,a_force_res_owner);
438   }                                               438   }
439                                                   439 
440   template <class TTO>                            440   template <class TTO>
441   bool convert(img<TTO>& a_res) const {           441   bool convert(img<TTO>& a_res) const {
442     a_res.make_empty();                           442     a_res.make_empty();
443                                                   443 
444     unsigned int sz = m_w*m_h*m_n;                444     unsigned int sz = m_w*m_h*m_n;
445     if(!sz) return false;                         445     if(!sz) return false;
446                                                   446 
447     TTO* _buffer = new TTO[sz];                   447     TTO* _buffer = new TTO[sz];
448     if(!_buffer) return false;                    448     if(!_buffer) return false;
449                                                   449 
450     unsigned int i,j,ipix,imn;                    450     unsigned int i,j,ipix,imn;
451     unsigned int mwn = m_w*m_n;                   451     unsigned int mwn = m_w*m_n;
452     T* _pos;T* pos;                               452     T* _pos;T* pos;
453     TTO* _rpos;TTO* rpos;                         453     TTO* _rpos;TTO* rpos;
454                                                   454 
455     for(j=0;j<m_h;j++) {                          455     for(j=0;j<m_h;j++) {
456       _pos = m_buffer + j*mwn;                    456       _pos = m_buffer + j*mwn;
457       _rpos = _buffer + j*mwn;                    457       _rpos = _buffer + j*mwn;
458       for(i=0;i<m_w;i++) {                        458       for(i=0;i<m_w;i++) {
459         imn = i*m_n;                              459         imn = i*m_n;
460         pos = _pos + imn;                         460         pos = _pos + imn;
461         rpos = _rpos + imn;                       461         rpos = _rpos + imn;
462         for(ipix=0;ipix<m_n;ipix++,pos++,rpos+    462         for(ipix=0;ipix<m_n;ipix++,pos++,rpos++) *rpos = *pos;
463       }                                           463       }
464     }                                             464     }
465                                                   465 
466     a_res.set(m_w,m_h,m_n,_buffer,true);          466     a_res.set(m_w,m_h,m_n,_buffer,true);
467     return true;                                  467     return true;
468   }                                               468   }
469                                                   469 
470   bool get_part(unsigned int a_sx,unsigned int    470   bool get_part(unsigned int a_sx,unsigned int a_sy,unsigned int a_sw,unsigned int a_sh,img<T>& a_res) const {
471                                                   471 
472     if((a_sx>=m_w)||(a_sy>=m_h)){                 472     if((a_sx>=m_w)||(a_sy>=m_h)){
473       a_res.make_empty();                         473       a_res.make_empty();
474       return false;                               474       return false;
475     }                                             475     }
476                                                   476 
477     // 012345                                     477     // 012345
478     unsigned int rw = min_of<unsigned int>(m_w    478     unsigned int rw = min_of<unsigned int>(m_w-a_sx,a_sw);
479     unsigned int rh = min_of<unsigned int>(m_h    479     unsigned int rh = min_of<unsigned int>(m_h-a_sy,a_sh);
480     unsigned int sz = rh*rw*m_n;                  480     unsigned int sz = rh*rw*m_n;
481     if(!sz) {                                     481     if(!sz) {
482       a_res.make_empty();                         482       a_res.make_empty();
483       return false;                               483       return false;
484     }                                             484     }
485                                                   485 
486     T* rb = new T[sz];                            486     T* rb = new T[sz];
487     if(!rb) {                                     487     if(!rb) {
488       a_res.make_empty();                         488       a_res.make_empty();
489       return false;                               489       return false;
490     }                                             490     }
491                                                   491 
492     unsigned int rstride = rw * m_n;              492     unsigned int rstride = rw * m_n;
493     T* rpos = rb;                                 493     T* rpos = rb;
494                                                   494 
495     unsigned int stride = m_w * m_n;              495     unsigned int stride = m_w * m_n;
496     T* pos = m_buffer+a_sy*stride+a_sx*m_n;       496     T* pos = m_buffer+a_sy*stride+a_sx*m_n;
497                                                   497 
498     //T* mx = m_buffer+size();                    498     //T* mx = m_buffer+size();
499     //T* rmx = rb+sz*sizeof(T);                   499     //T* rmx = rb+sz*sizeof(T);
500                                                   500 
501     for(unsigned int j=0;j<rh;j++,rpos+=rstrid    501     for(unsigned int j=0;j<rh;j++,rpos+=rstride,pos+=stride) {//j=0 -> bottom.
502 /*                                                502 /*
503       if((pos+rstride*sizeof(T))>mx) {            503       if((pos+rstride*sizeof(T))>mx) {
504         ::printf("debug : get_part : buffer ov    504         ::printf("debug : get_part : buffer overflow\n");
505         delete [] rb;                             505         delete [] rb;
506         a_res.make_empty();                       506         a_res.make_empty();
507         return false;                             507         return false;
508       }                                           508       }
509       if((rpos+rstride*sizeof(T))>rmx) {          509       if((rpos+rstride*sizeof(T))>rmx) {
510         ::printf("debug : get_part : result bu    510         ::printf("debug : get_part : result buffer overflow\n");
511         delete [] rb;                             511         delete [] rb;
512         a_res.make_empty();                       512         a_res.make_empty();
513         return false;                             513         return false;
514       }                                           514       }
515 */                                                515 */
516       ::memcpy(rpos,pos,rstride*sizeof(T));       516       ::memcpy(rpos,pos,rstride*sizeof(T));
517     }                                             517     }
518                                                   518 
519     a_res.set(rw,rh,m_n,rb,true);                 519     a_res.set(rw,rh,m_n,rb,true);
520     return true;                                  520     return true;
521   }                                               521   }
522                                                   522 
523   bool to_texture(bool a_expand,                  523   bool to_texture(bool a_expand,
524                   const T a_pixel[], //size sh    524                   const T a_pixel[], //size shoulde be a_img.m_n.
525                   img<T>& a_res,bool a_res_for    525                   img<T>& a_res,bool a_res_force_owner = true) const {
526                                                   526 
527     //NOTE : pixels of the original image are     527     //NOTE : pixels of the original image are not expanded or shrinked.
528                                                   528 
529     if((!m_w)||(!m_h)) {                          529     if((!m_w)||(!m_h)) {
530       a_res.make_empty();                         530       a_res.make_empty();
531       return false;                               531       return false;
532     }                                             532     }
533                                                   533 
534     // in case (m_w==1)||(m_h==1), expand the     534     // in case (m_w==1)||(m_h==1), expand the pixel
535     // up to the closest power of 2 ?             535     // up to the closest power of 2 ?
536                                                   536 
537     if((m_w==1)||(m_h==1)||a_expand) {            537     if((m_w==1)||(m_h==1)||a_expand) {
538       // find closest power of two upper than     538       // find closest power of two upper than m_w, m_h :
539       unsigned int rw = 2;                        539       unsigned int rw = 2;
540       while(true) {if(rw>=m_w) break;rw *=2;}     540       while(true) {if(rw>=m_w) break;rw *=2;}
541       unsigned int rh = 2;                        541       unsigned int rh = 2;
542       while(true) {if(rh>=m_h) break;rh *=2;}     542       while(true) {if(rh>=m_h) break;rh *=2;}
543                                                   543 
544       if((rw==m_w)&&(rh==m_h)) { //exact match    544       if((rw==m_w)&&(rh==m_h)) { //exact match.
545         if(a_res_force_owner) {                   545         if(a_res_force_owner) {
546           a_res.copy(m_w,m_h,m_n,m_buffer);       546           a_res.copy(m_w,m_h,m_n,m_buffer);
547         } else {                                  547         } else {
548           a_res.set(m_w,m_h,m_n,m_buffer,false    548           a_res.set(m_w,m_h,m_n,m_buffer,false); //WARNING owner=false.
549         }                                         549         }
550         return true;                              550         return true;
551       }                                           551       }
552                                                   552 
553       // we expand the image and fill new spac    553       // we expand the image and fill new spaces with a_pixel.
554                                                   554 
555       T* rb = 0;                                  555       T* rb = 0;
556       bool res_set = true;                        556       bool res_set = true;
557       if(a_res.owner()&&(a_res.size()==(rh*rw*    557       if(a_res.owner()&&(a_res.size()==(rh*rw*m_n))) {
558         // a_res has already the right allocat    558         // a_res has already the right allocation.
559         rb = a_res.buffer();                      559         rb = a_res.buffer();
560         res_set = false;                          560         res_set = false;
561       } else {                                    561       } else {
562         rb = new T[rh*rw*m_n];                    562         rb = new T[rh*rw*m_n];
563         if(!rb) {                                 563         if(!rb) {
564           a_res.make_empty();                     564           a_res.make_empty();
565           return false;                           565           return false;
566         }                                         566         }
567       }                                           567       }
568                                                   568 
569       unsigned int num = rw*m_n;                  569       unsigned int num = rw*m_n;
570                                                   570 
571       // initialize with given color :            571       // initialize with given color :
572      {T* pos = rb;                                572      {T* pos = rb;
573       for(unsigned int i=0;i<rw;i++,pos+=m_n)     573       for(unsigned int i=0;i<rw;i++,pos+=m_n) {
574         ::memcpy(pos,a_pixel,m_n*sizeof(T));      574         ::memcpy(pos,a_pixel,m_n*sizeof(T));
575       }                                           575       }
576       unsigned int sz = num*sizeof(T);            576       unsigned int sz = num*sizeof(T);
577       for(unsigned int j=1;j<rh;j++,pos+=num)     577       for(unsigned int j=1;j<rh;j++,pos+=num) {  //j=0 -> bottom.
578         ::memcpy(pos,rb,sz);                      578         ::memcpy(pos,rb,sz);
579       }}                                          579       }}
580                                                   580 
581       // center :                                 581       // center :
582       unsigned int col = (rw-m_w)/2;              582       unsigned int col = (rw-m_w)/2;
583       unsigned int row = (rh-m_h)/2;              583       unsigned int row = (rh-m_h)/2;
584                                                   584 
585       unsigned int mnum = m_w*m_n;                585       unsigned int mnum = m_w*m_n;
586                                                   586 
587       // copy original image in a centered par    587       // copy original image in a centered part of the new one :
588      {T* pos = m_buffer;                          588      {T* pos = m_buffer;
589       T* rpos = rb+row*num+col*m_n;               589       T* rpos = rb+row*num+col*m_n;
590       unsigned int sz = mnum*sizeof(T);           590       unsigned int sz = mnum*sizeof(T);
591       for(unsigned int j=0;j<m_h;j++,pos+=mnum    591       for(unsigned int j=0;j<m_h;j++,pos+=mnum,rpos+=num) {
592         ::memcpy(rpos,pos,sz);                    592         ::memcpy(rpos,pos,sz);
593       }}                                          593       }}
594                                                   594 
595       if(res_set) a_res.set(rw,rh,m_n,rb,true)    595       if(res_set) a_res.set(rw,rh,m_n,rb,true);
596                                                   596 
597       return true;                                597       return true;
598     } else {                                      598     } else {
599       // then m_w>=2 and m_h>=2                   599       // then m_w>=2 and m_h>=2
600                                                   600 
601       // find closest power of two lower than     601       // find closest power of two lower than m_w, m_h :
602       unsigned int sw = 2;                        602       unsigned int sw = 2;
603       while(true) {if((sw*2)>m_w) break;sw *=2    603       while(true) {if((sw*2)>m_w) break;sw *=2;}
604       unsigned int sh = 2;                        604       unsigned int sh = 2;
605       while(true) {if((sh*2)>m_h) break;sh *=2    605       while(true) {if((sh*2)>m_h) break;sh *=2;}
606                                                   606 
607       if((sw==m_w)&&(sh==m_h)) { //exact match    607       if((sw==m_w)&&(sh==m_h)) { //exact match.
608         if(a_res_force_owner) {                   608         if(a_res_force_owner) {
609           a_res.copy(m_w,m_h,m_n,m_buffer);       609           a_res.copy(m_w,m_h,m_n,m_buffer);
610         } else {                                  610         } else {
611           a_res.set(m_w,m_h,m_n,m_buffer,false    611           a_res.set(m_w,m_h,m_n,m_buffer,false); //WARNING owner=false.
612         }                                         612         }
613         return true;                              613         return true;
614       }                                           614       }
615                                                   615 
616       unsigned int sx = (m_w-sw)/2;               616       unsigned int sx = (m_w-sw)/2;
617       unsigned int sy = (m_h-sh)/2;               617       unsigned int sy = (m_h-sh)/2;
618                                                   618 
619       return get_part(sx,sy,sw,sh,a_res);         619       return get_part(sx,sy,sw,sh,a_res);
620     }                                             620     }
621                                                   621 
622   }                                               622   }
623                                                   623 
624   bool check_gl_limit(unsigned int a_GL_MAX_TE    624   bool check_gl_limit(unsigned int a_GL_MAX_TEXTURE_SIZE,img<T>& a_res) const {
625     // if ret true and a_res.is_empty(), "this    625     // if ret true and a_res.is_empty(), "this" does not exceeds the limit.
626     // if ret true and !a_res.is_empty(), "thi    626     // if ret true and !a_res.is_empty(), "this" exceeds the limit and a new fitting image is returned in a_res.
627     // if ret false, "this" exceeds the limit     627     // if ret false, "this" exceeds the limit but something went wrong in building a_res.
628     unsigned int tw = m_w;                        628     unsigned int tw = m_w;
629     unsigned int th = m_h;                        629     unsigned int th = m_h;
630     if((tw<=a_GL_MAX_TEXTURE_SIZE)&&(th<=a_GL_    630     if((tw<=a_GL_MAX_TEXTURE_SIZE)&&(th<=a_GL_MAX_TEXTURE_SIZE)) {
631       a_res.make_empty();                         631       a_res.make_empty();
632       return true;                                632       return true;
633     }                                             633     }
634     unsigned int fac = 2;                         634     unsigned int fac = 2;
635     while(true) {                                 635     while(true) {
636       unsigned int pw = tw/fac;                   636       unsigned int pw = tw/fac;
637       unsigned int ph = th/fac;                   637       unsigned int ph = th/fac;
638       if((pw<=a_GL_MAX_TEXTURE_SIZE)&&(ph<=a_G    638       if((pw<=a_GL_MAX_TEXTURE_SIZE)&&(ph<=a_GL_MAX_TEXTURE_SIZE)) {
639         //unsigned int sx = (tw-pw)/2;            639         //unsigned int sx = (tw-pw)/2;
640         //unsigned int sy = (th-ph)/2;            640         //unsigned int sy = (th-ph)/2;
641         //if(!get_part(sx,sy,pw,ph,a_res)) {      641         //if(!get_part(sx,sy,pw,ph,a_res)) {
642         if(!contract(fac,a_res)) {                642         if(!contract(fac,a_res)) {
643           a_res.make_empty();                     643           a_res.make_empty();
644           return false;                           644           return false;
645         }                                         645         }
646         return true;                              646         return true;
647       }                                           647       }
648       fac *= 2;                                   648       fac *= 2;
649     }                                             649     }
650     a_res.make_empty();                           650     a_res.make_empty();
651     return false;                                 651     return false;
652   }                                               652   }
653                                                   653 
654   bool bw2x(unsigned int a_n,img<T>& a_res) co    654   bool bw2x(unsigned int a_n,img<T>& a_res) const {
655     //expect a bw img.                            655     //expect a bw img.
656     if(m_n!=1) return false;                      656     if(m_n!=1) return false;
657                                                   657 
658     a_res.make_empty();                           658     a_res.make_empty();
659     if(a_n<m_n) return false;                     659     if(a_n<m_n) return false;
660     unsigned int sz = m_w*m_h*a_n;                660     unsigned int sz = m_w*m_h*a_n;
661     if(!sz) return false;                         661     if(!sz) return false;
662                                                   662 
663     a_res.m_buffer = new T[sz];                   663     a_res.m_buffer = new T[sz];
664     if(!a_res.m_buffer) return false;             664     if(!a_res.m_buffer) return false;
665     a_res.m_owner = true;                         665     a_res.m_owner = true;
666     a_res.m_w = m_w;                              666     a_res.m_w = m_w;
667     a_res.m_h = m_h;                              667     a_res.m_h = m_h;
668     a_res.m_n = a_n;                              668     a_res.m_n = a_n;
669                                                   669 
670     for(unsigned int j=0;j<m_h;j++) {             670     for(unsigned int j=0;j<m_h;j++) {
671       for(unsigned int i=0;i<m_w;i++) {           671       for(unsigned int i=0;i<m_w;i++) {
672         //position in the original image.         672         //position in the original image.
673         T* pos = m_buffer + j * (m_w * m_n) +     673         T* pos = m_buffer + j * (m_w * m_n) + i*m_n;
674                                                   674 
675         T* rpos = a_res.m_buffer + j * (m_w *     675         T* rpos = a_res.m_buffer + j * (m_w * a_n) + i*a_n;
676                                                   676 
677         for(unsigned int ipix=0;ipix<a_n;ipix+    677         for(unsigned int ipix=0;ipix<a_n;ipix++) {
678           *(rpos+ipix) = *pos;                    678           *(rpos+ipix) = *pos;
679         }                                         679         }
680                                                   680 
681       }                                           681       }
682     }                                             682     }
683                                                   683 
684     return true;                                  684     return true;
685   }                                               685   }
686                                                   686 
687   bool yswap(img<T>& a_res) const {               687   bool yswap(img<T>& a_res) const {
688     a_res.make_empty();                           688     a_res.make_empty();
689                                                   689 
690     a_res.m_buffer = new T[size()];               690     a_res.m_buffer = new T[size()];
691     if(!a_res.m_buffer) return false;             691     if(!a_res.m_buffer) return false;
692     a_res.m_owner = true;                         692     a_res.m_owner = true;
693     a_res.m_w = m_w;                              693     a_res.m_w = m_w;
694     a_res.m_h = m_h;                              694     a_res.m_h = m_h;
695     a_res.m_n = m_n;                              695     a_res.m_n = m_n;
696                                                   696 
697     unsigned int stride = m_w * m_n;              697     unsigned int stride = m_w * m_n;
698                                                   698 
699     for(unsigned int j=0;j<m_h;j++) {             699     for(unsigned int j=0;j<m_h;j++) {
700       T* pos = m_buffer + j * stride;             700       T* pos = m_buffer + j * stride;
701       T* rpos = a_res.m_buffer + (m_h-j-1) * s    701       T* rpos = a_res.m_buffer + (m_h-j-1) * stride;
702       ::memcpy(rpos,pos,stride*sizeof(T));        702       ::memcpy(rpos,pos,stride*sizeof(T));
703     }                                             703     }
704                                                   704 
705     return true;                                  705     return true;
706   }                                               706   }
707                                                   707 
708   bool rgba2rgb(img<T>& a_res) const {            708   bool rgba2rgb(img<T>& a_res) const {
709     if(m_n!=4) return false;                      709     if(m_n!=4) return false;
710                                                   710 
711     unsigned int a_n = 3;                         711     unsigned int a_n = 3;
712                                                   712 
713     a_res.make_empty();                           713     a_res.make_empty();
714     unsigned int sz = m_w*m_h*a_n;                714     unsigned int sz = m_w*m_h*a_n;
715     if(!sz) return false;                         715     if(!sz) return false;
716                                                   716 
717     a_res.m_buffer = new T[sz];                   717     a_res.m_buffer = new T[sz];
718     if(!a_res.m_buffer) return false;             718     if(!a_res.m_buffer) return false;
719     a_res.m_owner = true;                         719     a_res.m_owner = true;
720     a_res.m_w = m_w;                              720     a_res.m_w = m_w;
721     a_res.m_h = m_h;                              721     a_res.m_h = m_h;
722     a_res.m_n = a_n;                              722     a_res.m_n = a_n;
723                                                   723 
724     for(unsigned int j=0;j<m_h;j++) {             724     for(unsigned int j=0;j<m_h;j++) {
725       for(unsigned int i=0;i<m_w;i++) {           725       for(unsigned int i=0;i<m_w;i++) {
726         //position in the original image.         726         //position in the original image.
727         T* pos = m_buffer + j * (m_w * m_n) +     727         T* pos = m_buffer + j * (m_w * m_n) + i*m_n;
728                                                   728 
729         T* rpos = a_res.m_buffer + j * (m_w *     729         T* rpos = a_res.m_buffer + j * (m_w * a_n) + i*a_n;
730                                                   730 
731         for(unsigned int ipix=0;ipix<a_n;ipix+    731         for(unsigned int ipix=0;ipix<a_n;ipix++) {
732           *(rpos+ipix) = *(pos+ipix);             732           *(rpos+ipix) = *(pos+ipix);
733         }                                         733         }
734                                                   734 
735       }                                           735       }
736     }                                             736     }
737                                                   737 
738     return true;                                  738     return true;
739   }                                               739   }
740                                                   740 
741   bool rgb2rgba(img<T>& a_res,const T& a_pixel    741   bool rgb2rgba(img<T>& a_res,const T& a_pixel) const {
742     if(m_n!=3) return false;                      742     if(m_n!=3) return false;
743                                                   743 
744     unsigned int n = 4;                           744     unsigned int n = 4;
745                                                   745 
746     a_res.make_empty();                           746     a_res.make_empty();
747     unsigned int sz = m_w*m_h*n;                  747     unsigned int sz = m_w*m_h*n;
748     if(!sz) return false;                         748     if(!sz) return false;
749                                                   749 
750     a_res.m_buffer = new T[sz];                   750     a_res.m_buffer = new T[sz];
751     if(!a_res.m_buffer) return false;             751     if(!a_res.m_buffer) return false;
752     a_res.m_owner = true;                         752     a_res.m_owner = true;
753     a_res.m_w = m_w;                              753     a_res.m_w = m_w;
754     a_res.m_h = m_h;                              754     a_res.m_h = m_h;
755     a_res.m_n = n;                                755     a_res.m_n = n;
756                                                   756 
757     for(unsigned int j=0;j<m_h;j++) {             757     for(unsigned int j=0;j<m_h;j++) {
758       for(unsigned int i=0;i<m_w;i++) {           758       for(unsigned int i=0;i<m_w;i++) {
759         //position in the original image.         759         //position in the original image.
760         T* pos = m_buffer + j * (m_w * m_n) +     760         T* pos = m_buffer + j * (m_w * m_n) + i*m_n;
761                                                   761 
762         T* rpos = a_res.m_buffer + j * (m_w *     762         T* rpos = a_res.m_buffer + j * (m_w * n) + i*n;
763                                                   763 
764         *(rpos+0) = *(pos+0);                     764         *(rpos+0) = *(pos+0);
765         *(rpos+1) = *(pos+1);                     765         *(rpos+1) = *(pos+1);
766         *(rpos+2) = *(pos+2);                     766         *(rpos+2) = *(pos+2);
767         *(rpos+3) = a_pixel;                      767         *(rpos+3) = a_pixel;
768                                                   768 
769       }                                           769       }
770     }                                             770     }
771                                                   771 
772     return true;                                  772     return true;
773   }                                               773   }
774                                                   774 
775   bool rgba2bgra() {                              775   bool rgba2bgra() {
776     if(m_n!=4) return false;                      776     if(m_n!=4) return false;
777     for(unsigned int j=0;j<m_h;j++) {             777     for(unsigned int j=0;j<m_h;j++) {
778       for(unsigned int i=0;i<m_w;i++) {           778       for(unsigned int i=0;i<m_w;i++) {
779         T* pos = m_buffer + j * (m_w * m_n) +     779         T* pos = m_buffer + j * (m_w * m_n) + i*m_n;
780         T r = *(pos+0);                           780         T r = *(pos+0);
781         T g = *(pos+1);                           781         T g = *(pos+1);
782         T b = *(pos+2);                           782         T b = *(pos+2);
783         T a = *(pos+3);                           783         T a = *(pos+3);
784         *(pos+0) = b;                             784         *(pos+0) = b;
785         *(pos+1) = g;                             785         *(pos+1) = g;
786         *(pos+2) = r;                             786         *(pos+2) = r;
787         *(pos+3) = a;                             787         *(pos+3) = a;
788       }                                           788       }
789     }                                             789     }
790     return true;                                  790     return true;
791   }                                               791   }
792                                                   792 
793 public:                                           793 public:
794   static bool concatenate(const std::vector< i    794   static bool concatenate(const std::vector< img<T> >& a_imgs,
795                           unsigned int a_cols,    795                           unsigned int a_cols,unsigned int a_rows,
796                           unsigned int a_bw,un    796                           unsigned int a_bw,unsigned int a_bh,
797                           T a_bc, //border gre    797                           T a_bc, //border grey level.
798                           img<T>& a_res){         798                           img<T>& a_res){
799     // We assume that a_imgs.size() is a_cols*    799     // We assume that a_imgs.size() is a_cols*a_rows and that all images have same (w,h,bpp).
800                                                   800 
801     unsigned int num = a_cols*a_rows;             801     unsigned int num = a_cols*a_rows;
802     if(!num) {a_res.make_empty();return false;    802     if(!num) {a_res.make_empty();return false;}
803                                                   803 
804     unsigned int aw = a_imgs[0].m_w;              804     unsigned int aw = a_imgs[0].m_w;
805     unsigned int ah = a_imgs[0].m_h;              805     unsigned int ah = a_imgs[0].m_h;
806     unsigned int an = a_imgs[0].m_n;              806     unsigned int an = a_imgs[0].m_n;
807                                                   807 
808     for(unsigned int index=1;index<num;index++    808     for(unsigned int index=1;index<num;index++) {
809       if(a_imgs[index].m_n!=an) {                 809       if(a_imgs[index].m_n!=an) {
810         a_res.make_empty();                       810         a_res.make_empty();
811         return false;                             811         return false;
812       }                                           812       }
813       if(a_imgs[index].m_w!=aw) {                 813       if(a_imgs[index].m_w!=aw) {
814         a_res.make_empty();                       814         a_res.make_empty();
815         return false;                             815         return false;
816       }                                           816       }
817       if(a_imgs[index].m_h!=ah) {                 817       if(a_imgs[index].m_h!=ah) {
818         a_res.make_empty();                       818         a_res.make_empty();
819         return false;                             819         return false;
820       }                                           820       }
821     }                                             821     }
822                                                   822 
823     unsigned int wbw = aw + 2*a_bw;               823     unsigned int wbw = aw + 2*a_bw;
824     unsigned int hbh = ah + 2*a_bh;               824     unsigned int hbh = ah + 2*a_bh;
825                                                   825 
826     unsigned int rw = wbw * a_cols;               826     unsigned int rw = wbw * a_cols;
827     unsigned int rh = hbh * a_rows;               827     unsigned int rh = hbh * a_rows;
828     unsigned int rn = an;                         828     unsigned int rn = an;
829                                                   829 
830     //printf("debug : %d %d\n",rw,rh);            830     //printf("debug : %d %d\n",rw,rh);
831                                                   831 
832     // on big concatenated image the below may    832     // on big concatenated image the below may fail :
833     unsigned int rsz = rh*rw*rn;                  833     unsigned int rsz = rh*rw*rn;
834     T* rb = new T[rsz];                           834     T* rb = new T[rsz];
835     if(!rb) {                                     835     if(!rb) {
836       a_res.make_empty();                         836       a_res.make_empty();
837       return false;                               837       return false;
838     }                                             838     }
839                                                   839 
840     bool has_border = a_bw||a_bh?true:false;      840     bool has_border = a_bw||a_bh?true:false;
841     if(has_border) {                              841     if(has_border) {
842       ::memset(rb,a_bc,rsz*sizeof(T));            842       ::memset(rb,a_bc,rsz*sizeof(T));
843     }                                             843     }
844                                                   844 
845     //optimize :                                  845     //optimize :
846     //unsigned int wbwn = wbw*an;                 846     //unsigned int wbwn = wbw*an;
847     unsigned int awn = aw*an;                     847     unsigned int awn = aw*an;
848     unsigned int rwn = rw*an;                     848     unsigned int rwn = rw*an;
849     unsigned int i,j,r;                           849     unsigned int i,j,r;
850     //unsigned int c;                             850     //unsigned int c;
851     T* pos;T* ptile;T* _pos;                      851     T* pos;T* ptile;T* _pos;
852                                                   852 
853     //copy tiles :                                853     //copy tiles :
854     unsigned int index = 0;                       854     unsigned int index = 0;
855     for(j=0;j<a_rows;j++) {                       855     for(j=0;j<a_rows;j++) {
856       for(i=0;i<a_cols;i++) {                     856       for(i=0;i<a_cols;i++) {
857         // index = a_cols*j+i                     857         // index = a_cols*j+i
858         const T* tile = a_imgs[index].buffer()    858         const T* tile = a_imgs[index].buffer();
859                                                   859 
860         //if(has_border) {                        860         //if(has_border) {
861         //  for(unsigned int r=0;r<hbh;r++) {     861         //  for(unsigned int r=0;r<hbh;r++) {
862         //    T* pos = rb + (j*hbh+r)*rwn + i*    862         //    T* pos = rb + (j*hbh+r)*rwn + i*wbwn;
863         //    ::memset(pos,a_bc,wbwn*sizeof(T)    863         //    ::memset(pos,a_bc,wbwn*sizeof(T));
864         //  }                                     864         //  }
865         //}                                       865         //}
866                                                   866 
867         _pos = rb + (j*hbh+a_bh)*rwn + (i*wbw+    867         _pos = rb + (j*hbh+a_bh)*rwn + (i*wbw+a_bw)*rn;
868        {for(r=0;r<ah;r++) {                       868        {for(r=0;r<ah;r++) {
869 //          pos = _pos + r*rwn;                   869 //          pos = _pos + r*rwn;
870 //          ptile = tile + r*awn;                 870 //          ptile = tile + r*awn;
871 //          for(c=0;c<awn;c++,pos++,ptile++) *    871 //          for(c=0;c<awn;c++,pos++,ptile++) *pos = *ptile;
872           ::memcpy(_pos+r*rwn,tile+r*awn,awn*s    872           ::memcpy(_pos+r*rwn,tile+r*awn,awn*sizeof(T)); //optimize. (bof, we do not gain a lot).
873         }}                                        873         }}
874                                                   874 
875         index++;                                  875         index++;
876       }                                           876       }
877     }                                             877     }
878                                                   878 
879     a_res.set(rw,rh,rn,rb,true);                  879     a_res.set(rw,rh,rn,rb,true);
880     return true;                                  880     return true;
881   }                                               881   }
882                                                   882 
883 protected:                                        883 protected:
884   unsigned int m_w;                               884   unsigned int m_w;
885   unsigned int m_h;                               885   unsigned int m_h;
886   unsigned int m_n;                               886   unsigned int m_n;
887   T* m_buffer;                                    887   T* m_buffer;
888   bool m_owner;                                   888   bool m_owner;
889                                                   889 
890 private: static void check_instantiation() {im    890 private: static void check_instantiation() {img<float> dummy;}
891 };                                                891 };
892                                                   892 
893                                                   893 
894 typedef img<unsigned char> img_byte;              894 typedef img<unsigned char> img_byte;
895                                                   895 
896 // NOTE : img_byte is ready for OpenGL glTexIm    896 // NOTE : img_byte is ready for OpenGL glTexImage2D UNSIGNED_BYTE RGB.
897 //        For glTexImage2D, first row in m_buf    897 //        For glTexImage2D, first row in m_buffer is bottom of image.
898                                                   898 
899 inline void tex_expand_size(unsigned int a_w,u    899 inline void tex_expand_size(unsigned int a_w,unsigned int& a_h,
900                             unsigned int& a_ew    900                             unsigned int& a_ew,unsigned int& a_eh){
901   // find closest power of two upper than a_w,    901   // find closest power of two upper than a_w, a_h :
902   a_ew = 2;                                       902   a_ew = 2;
903   while(true) {if(a_ew>=a_w) break;a_ew *=2;}     903   while(true) {if(a_ew>=a_w) break;a_ew *=2;}
904   a_eh = 2;                                       904   a_eh = 2;
905   while(true) {if(a_eh>=a_h) break;a_eh *=2;}     905   while(true) {if(a_eh>=a_h) break;a_eh *=2;}
906 }                                                 906 }
907                                                   907 
908 }                                                 908 }
909                                                   909 
910 #endif                                            910 #endif